Загрузка части форм из сервера с валидацией

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Аватара пользователя
bemulima
Сообщения: 207
Зарегистрирован: 2012.12.20, 09:41
Откуда: Курган

Загрузка части форм из сервера с валидацией

Сообщение bemulima »

Добрый день! Есть большая ActiveForm форма (композитная), которая состоит из частей. Изначально отображаются только базовые поля, далее клиент может добавить дополнительные поля, которые загружаются из сервера. Как добиться того, что бы при загрузки части форм, загружались вместе со jquery скриптом для валидация? :?

Сейчас клиентская валидация работает только для базовых полей а для загруженных полей после сабмита если валидацию на сервере прошла после перезагрузки работает.
Аватара пользователя
bemulima
Сообщения: 207
Зарегистрирован: 2012.12.20, 09:41
Откуда: Курган

Re: Загрузка части форм из сервера с валидацией

Сообщение bemulima »

Пока временно решил, с помощью pjax: на фоне отправляет всю форму на сервер и если валидацию не прошла то полученный html заменяет. Не думаю, что это хорошее решение особенно, когда форма большая.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Загрузка части форм из сервера с валидацией

Сообщение yiiliveext »

В экшине вместе с отрисованными полями передаете массив атрибутов для валидации. На клиенте ловите и в цикле добавляете через $("#my-form").yiiActiveForm("add", attribute);
Аватара пользователя
bemulima
Сообщения: 207
Зарегистрирован: 2012.12.20, 09:41
Откуда: Курган

Re: Загрузка части форм из сервера с валидацией

Сообщение bemulima »

yiiliveext писал(а): 2019.09.06, 22:18 В экшине вместе с отрисованными полями передаете массив атрибутов для валидации. На клиенте ловите и в цикле добавляете через $("#my-form").yiiActiveForm("add", attribute);
Как раз так и делаю, проблема в том, что выдает ошибку yii.validation is undefined

Получаю такие аттрибуты

Код: Выделить всё

[
{
    "id": "formexperience-0-post",
    "name": "[0]post",
    "container": ".field-formexperience-0-post",
    "input": "#formexperience-0-post",
    "error": ".invalid-feedback",
    "validate": function(attribute, value, messages, deferred, $form)
    {
        yii.validation.required(value, messages,
        {
            "message": "Необходимо заполнить «Должность»."
        });
        yii.validation.string(value, messages,
        {
            "message": "Значение «Должность» должно быть строкой.",
            "max": 255,
            "tooLong": "Значение «Должность» должно содержать максимум 255 символов.",
            "skipOnEmpty": 1
        });
    }
},
{
    "id": "formexperience-0-company_name",
    "name": "[0]company_name",
    "container": ".field-formexperience-0-company_name",
    "input": "#formexperience-0-company_name",
    "error": ".invalid-feedback",
    "validate": function(attribute, value, messages, deferred, $form)
    {
        yii.validation.required(value, messages,
        {
            "message": "Необходимо заполнить «Компания»."
        });
        yii.validation.string(value, messages,
        {
            "message": "Значение «Компания» должно быть строкой.",
            "max": 255,
            "tooLong": "Значение «Компания» должно содержать максимум 255 символов.",
            "skipOnEmpty": 1
        });
    }
},
...
]
полученные аттрибуты перевожу в код и храню в шаблоне (У меня композитная мультипл форма, при нажатии "добавить" отправляю запрос на сервер, получаю и храню в шаблоне и от туда беру и отображаю форму, если клиент нажал еще добавить, то уже беру из шаблона, каждый раз, когда добавляется или удаляется форма ключи переписываю.)

Код: Выделить всё

template.content = response.content;
                    template.attributes= eval(response.validation.attributes.replace(/\\"/g, ''));//.rules.replace(/'/g, '"')
                    template.params = response.validation.params;
добавляю через цикл

Код: Выделить всё

for (let i = 0; i < template.attributes.length; i++) {
                        $('#form').yiiActiveForm('add', template.attributes[i]);
                    }
и в итоге yii.validation is undefined
Аватара пользователя
bemulima
Сообщения: 207
Зарегистрирован: 2012.12.20, 09:41
Откуда: Курган

Re: Загрузка части форм из сервера с валидацией

Сообщение bemulima »

аха, всё решил, подключил ValidationAsset::class и всё заработала.

Вообще считаю, может я еще не знаю, получить данные из ActiveForm::attributes не удобно, обязательно надо через каждое поле пройтись, а если тебе не нужна форма а просто аттрибуты? Лишние работы. Было бы проще если был метод из экшна типа $this->renderAttributes('_form', $model);
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Загрузка части форм из сервера с валидацией

Сообщение yiiliveext »

Action для добавления дополнительных полей

Код: Выделить всё

public function actionAddFields()
    {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        $someFormModel = new SomeFormModel();
        $form = new \yii\widgets\ActiveForm(['id' => 'main-form']);
        $fields = $this->renderPartial('some-form-fields', [  //если используете в полях виджеты, подгружающие js, то используйте renderAjax
            'form' => $form,
            'someFormModel' => $someFormModel
        ]);
        $attributes = [];
        foreach ($form->attributes as $attribute) {
            $attributes[] = json_encode($attribute);
        }

        return ['fields' => $fields, 'attributes' => $attributes];
    }
some-form-fields.php

Код: Выделить всё

<?php
    echo $form->field($someFormModel, 'field1')->textInput();
    echo $form->field($someFormModel, 'field2')->textInput();
    echo $form->field($someFormModel, 'field3')->textInput();
В основном представлении

Код: Выделить всё

<?php
$js = '
function addFields() {
    $.ajax({
        url: "/yourcontroller/add-fields",
        dataType: "json",
    }).done(function(data) {
       $("#form-extra-fields").append(data.fields);
       $.each(data.attributes, function (key, value) {
           var attribute = $.parseJSON(value);
           attribute.validate = eval("(function(){return " + attribute.validate.expression + ";})();"); 
           $("#main-form").yiiActiveForm("add", attribute);
       });
    });
}
';
$this->registerJs($js, \yii\web\View::POS_BEGIN);
Аватара пользователя
bemulima
Сообщения: 207
Зарегистрирован: 2012.12.20, 09:41
Откуда: Курган

Re: Загрузка части форм из сервера с валидацией

Сообщение bemulima »

yiiliveext писал(а): 2019.09.25, 10:07
Примерно всё так и делаю, только я не каждый раз запрашиваю форму из сервера а только если в хранилище шаблонов нету данной формы и ее аттрибуты. Только ради этого пришлось написать метод, который переименовывает ключи, каждый раз, когда добавляется или удаляется форма.
Аватара пользователя
bemulima
Сообщения: 207
Зарегистрирован: 2012.12.20, 09:41
Откуда: Курган

Re: Загрузка части форм из сервера с валидацией

Сообщение bemulima »

Возникла еще одна задача, ActiveForm::attributes получаю, а как подгружать зависимые скрипты и стили этой формы. Раньше решал вопрос $this->renderAjax, теперь всё отправляется через $this->asJson. Сейчас смотрю на содержание $this->view->js[] пытаюсь наколадвать, нужных скриптов каким то образом подключить в конец html кода.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Загрузка части форм из сервера с валидацией

Сообщение yiiliveext »

Никак. asJson() не для этого предназначен.
Аватара пользователя
bemulima
Сообщения: 207
Зарегистрирован: 2012.12.20, 09:41
Откуда: Курган

Re: Загрузка части форм из сервера с валидацией

Сообщение bemulima »

yiiliveext писал(а): 2019.09.25, 15:54 Никак. asJson() не для этого предназначен.
Не верится. Пока ищу способы. Должен же быть выход, как то передать в строке думаю можно.
Ответить