Как правильно использовать ajax валидацию для динамических полей?

Доброй ночи.
Есть форма, обрабатываются две модели.
Вторая модель для габаритов груза, длина, ширина, масса и так далее.
Для габаритов поля добавляются при помощи jquery.
<?php
$form = ActiveForm::begin([
    'id' => $idForm,
    'enableAjaxValidation' => true,
    'validationUrl' => Url::toRoute(['/proposal/default/ajax-validate']),
]);

?>
        <!-- габаритики -->
            <?php
               foreach($dimensions as $key => $dimension){
            ?>
                       <div class="b-calcColumnHeader">Длина (см)</div>
                       <?= $form->field($dimension, "[$key]length")->textInput([
                            'class' => 'b-calcInput',
                            'placeholder' => 'см',
                            //'pattern' => $model->pattern,
                            ])->label(false) ?>
                       <div class="b-calcColumnHeader">Ширина (см)</div>
                       <?= $form->field($dimension, "[$key]width")->textInput([
                            'class' => 'b-calcInput',
                            'placeholder' => 'см',
                            //'pattern' => $model->pattern,
                            ])->label(false) ?>

                       <div class="b-calcColumnHeader">Высота (см)</div>
                       <?= $form->field($dimension, "[$key]height")->textInput([
                            'class' => 'b-calcInput',
                            'placeholder' => 'см',
                            //'pattern' => $model->pattern,
                            ])->label(false) ?>

                       <div class="b-calcColumnHeader">Масса (кг)</div>
                       <?= $form->field($dimension, "[$key]mass")->textInput([
                            'class' => 'b-calcInput',
                            'placeholder' => 'кг',
                            //'pattern' => $model->pattern,
                            ])->label(false) ?>
                       
                       <div class="b-calcColumnHeader">Кол-во (шт)</div>
                       <?= $form->field($dimension, "[$key]qty")->textInput([
                            'class' => 'b-calcInput j-numMask',
                            'placeholder' => 'шт',
                            //'pattern' => '^[ 0-9]+$',
                            ])->label(false) ?>

            <?php
               }
            ?>
            <div class="b-cargoSize">
                <?php
                echo Html::button('- Удалить', ['class' => 'j-addFields b-removeFields', 'style' => 'display:none;']);
                echo Html::button('+ Ещё груз', ['class' => 'j-addFields b-addFields'])
                ?>
            </div>

Настроена ajax валидация. Проблема с проверкой второй формы, а именно полей, которые добавляются динамически.
Действие для ajax валидации
public function actionAjaxValidate()
    {
        if(Yii::$app->request->isAjax){

            $model = new CalculateForm();
            $model->scenario = CalculateForm::SCENARIO_CALC_FORM;
            
           /* проверка второй формы */ 
            if(Yii::$app->request->post('Dimensions')){
                $count = count(Yii::$app->request->post('Dimensions', []));
                $models = [new Dimensions()];

                for($i = 1; $i < $count; $i++){
                    $models[] = new Dimensions();
                }
                if(Model::loadMultiple($models, Yii::$app->request->post())){

                    Yii::$app->response->format = Response::FORMAT_JSON;
                    $dimensions = ActiveForm::validateMultiple($models);
                }

            }

            if($model->load(Yii::$app->request->post())){
                Yii::$app->response->format = Response::FORMAT_JSON;
                $calcform = ActiveForm::validate($model);
            }

            if(Yii::$app->request->post('Dimensions')){
                return ArrayHelper::merge($calcform, $dimensions);
            }
            else{
                return $calcform;
            }
        }
        return false;
    }

В виде есть js для обработки формы
$('form').on('beforeSubmit', function(e){
    $.ajax({
    
       type: form.attr('method'),
       url: form.attr('action'),
       data: dataAll
    
    }).done(function(data){
        if(data.success){
           console.log(data)
           ajaxAnswer(data)
           $('form').trigger('reset')
        }
        else if(data.validation){
           console.log('validate')
           ajaxAnswer(data)
        }
        else{
        
        }
    }).fail(function(){
        console.log('fail')
    })
    
    return false;
})

Пытался сделать проверку при помощи yiiActiveForm. Пока сделал для одного поля.
setTimeout(function(){
  $('form').yiiActiveForm('add',{  
     id: 'dimensions-lenght',
     name: '[]length',
     input: '#dimensions-lenght',
     container: '.field-dimensions-lenght',
     error: '.help-block',
     validate:  function (attribute, value, messages, deferred, form) {
        yii.validation.required(value, messages, {message: "Validation Message Here"})
     }
  })   
}, 500)
$('form').on('beforeSubmit', function(e){
   /* обработка формы */
})

Но ничего не происходит. Первый набор полей для габаритов валидируется, но ошибки валидации подставляются для всех полей.

Как правильно использовать yiiActiveForm для валидации динамических полей? И как использовать метод add для валидации нескольких полей?
  • Вопрос задан
  • 318 просмотров
Решения вопроса 1
slo_nik
@slo_nik Автор вопроса, куратор тега Yii
Задачу решил.
Решение не сильно элегантное и требует серьёзной доработки, но всё таки работает, а это самое главное. Хотя бы немного разобрался как добавить динамические поля в валидацию.
$(function () {
    $('form').find('.cargo-data').on('change', function(){
        var $form = $(this).parents('form');
        console.log($(this).parents('form').attr('id'));

        var input = $form.find('input');
        $form.on('keyup', function(){

            $(this).find('.b-cargoSizes input').each(function(){
                var input = $(this);

                $form.yiiActiveForm('add', {
                    id: input.attr('id'),
                    name: input.attr('name'),
                    container: '.field-' + input.attr('id'),
                    input: '#' + input.attr('id'),
                    error: '.help-block',
                    validateOnType: true,
                    validate: function(attribute, value, messages, deferred, $form) {
                        console.log(attribute + ' - ' + value);
                        yii.validation.required(value, messages, {message: "Заполнить обязательно!"});
                        yii.validation.number(value, messages, {
                            pattern: /^\s*\d+[,|.]*\d*\s*$/,
                            message: "Должно быть числом!"
                        });
                    }
                });
            })
        })
    });
});
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы