Yii2. Отправляем данные из ActiveForm через AJAX

Разберем как сделать ActiveForm полностью работающую через AJAX.

Нам нужно сделать следующее:

  • валидацию данных перед отправкой
  • отправку данных формы через AJAX
  • показ сообщений после отправки данных на сервер

Обычно view c ActiveForm выглядит так: 

<?php $form = \yii\widgets\ActiveForm::begin([
    'id' => 'my-form-id',
    'action' => 'save-url',
    'enableAjaxValidation' => true,
    'validationUrl' => 'my-validation-url',
]); ?>
<?= $form->field($model, 'email')->textInput(); ?>
<?= Html::submitButton('Save'); ?>
<?php $form->end(); ?>

Я предпочитаю делать отдельные методы для валидации формы, поэтому я указал свой урл валидации через свойство validationUrl и включил AJAX валидацию указав enableAjaxValidation = true.

В экшене валидации мы валидируем форму и возвращем список ошибок клиенту:


public function actionValidate()
{
    $model = new MyModel();
    $request = \Yii::$app->getRequest();
    if ($request->isPost && $model->load($request->post())) {
        \Yii::$app->response->format = Response::FORMAT_JSON;
        return ActiveForm::validate($model);
    }
}

И наконец делаем экшен для сохранения данных из формы:

public function actionSave()
{
    $model = new MyModel();
    $request = \Yii::$app->getRequest();
    if ($request->isPost && $model->load($request->post())) {
        \Yii::$app->response->format = Response::FORMAT_JSON;
        return ['success' => $model->save()];
    }
    return $this->renderAjax('myViewName', [
        'model' => $model,
    ]);
}

Для того что бы отправить данные через AJAX, нужно добавить свой обработчик события beforeSubmit. В обработчике мы должны самостоятельно отправить данные на сервер и отобразить ошибку если сервер не сохранил данные:


$('#contact-form').on('beforeSubmit', function () {
    var $yiiform = $(this);
// отправляем данные на сервер $.ajax({ type: $yiiform.attr('method'), url: $yiiform.attr('action'), data: $yiiform.serializeArray() } ) .done(function(data) { if(data.success) { // данные сохранены } else { // сервер вернул ошибку и не сохранил наши данные } }) .fail(function () { // не удалось выполнить запрос к серверу })
return false; // отменяем отправку данных формы

})

Вот и все что надо сделать :)