Yii2 → Ajax валидация в модальном окне

Задача: есть некая форма, которая подгружается через Ajax в модальном окне. Необходимо производить валидацию формы и в случае успеха перенаправить на нужную страницу.

Приведу два варианта решения поставленной задачи.

Решение #1

Основное представление:

<a id="modal-btn" data-target="/site/order">Заказать</a>
...
<?php
    yii\bootstrap\Modal::begin([
        'header' => 'Оформить заказ',
        'id' => 'modal',
        'size' => 'modal-md',       
    ]);
?>
<div id='modal-content'>Загружаю...</div>
<?php yii\bootstrap\Modal::end(); ?>

JavaScript:

    // Вызов модального окна формы заказа
    $('#modal-btn').on('click', function() {
        $('#modal').modal('show')
            .find('#modal-content')
            .load($(this).attr('data-target'));
    });

Контроллер:

public function actionOrder()
{
        $model = new Order;
        if ($model->load(Yii::$app->request->post()) && $model->save()) {            
                return $this->redirect('/site/confirm');
        }
        return $this->renderAjax('order', ['model' => $model]);
}

Представление формы может выглядеть приблизительно так:

<?php $form = ActiveForm::begin(['id' => 'order-form']); ?>
<?= $form->field($model, 'name') ?>
<?= $form->field($model, 'email') ?>
<div class="form-group">
    <?= Html::submitButton('Отправить', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>

Важный момент, для формы необходимо обязательно задать уникальное значение id (например order-form, как в примере выше), иначе Ajax валидация работать не будет

Решение #2

Приведу отличия. В представлении:

<?php $form = ActiveForm::begin([
    'id' => 'order-form',
    'enableAjaxValidation' => true,
]); ?>

В контроллере:

public function actionOrder()
{
        $model = new Order;
        if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
        if($model->save()) {
                return $this->redirect('/site/confirm');
        } else { 
            Yii::$app->response->format = Response::FORMAT_JSON;
            return ActiveForm::validate($model);
        }
        return $this->renderAjax('order', ['model' => $model]);       
}

Линк на документацию
Вики по теме

  • Tank Eu

    Спасибо

  • Эдуард Сарваров

    Спасибо! Полезная статья

  • Алексей Кан

    В вашем примере происходит двойная валидация данных через $model->save() и ActiveForm::validate($model).

  • Богдан

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

    if ($model->save())
    return $this->redirect([‘index’]);