@AlexWeb6667
Web-дизайнер с опытом FullStack разработки

Как отправить Active form Ajax запросом?

Решено, ответ ниже

Всем привет, уважаемые знатоки) разжуйте кому не лень плз, как правильно ActiveForm ajax-ом отправлять, немного запутался в способах.
Есть форма
<?php $form = ActiveForm::begin([
                'options' => [
                'id' => 'product-form',
                'enableAjaxValidation' => true
                ]
            ]); ?>


Нужно отправить форму ajax-ом, и если модель сохранена отрендрить другую вьюху вместо формы, без перезагрузки.

Как пробовал решать
1. Прописать в модели 'beforeSubmit' (Нашел где-то на форуме);
<?php $form = ActiveForm::begin([
            'beforeSubmit' => new \yii\web\JsExpression('function(form) {
                jQuery.ajax({
                    url: "'. $this->context->createUrl('create') .'",
                    type: "POST",
                    dataType: "json",
                    data: form.serialize(),
                    success: function(response) {
                        ...
                    },
                    error: function(response) {
                        ...
                    }
                });
                return false;
            }')
        ]);

На что получил в ответ, ActiveForm не знает значения 'beforeSubmit';

2.Прописал почти тоже самое и зарегистрировал в js блоке.
$(document).on("beforeSubmit", "#product-form", function () {
    
                var form = $(this).serialize();
             
                jQuery.ajax({
                    type: 'POST',
                    url: "/admin/feed/save",
                    data: {forma: form},
                    dataType: "json",
                    success: function (data) {
                        alert(data);
                    },
                    error: function (data) {
                        alert('беда');
                    }
                });
    
    });

И все равно столкнулся с проблемами

a)Запрос все время возвращается ерорсами, хотя в логах все чисто( при этом логики в обработчике не прописано, просто return "ок"; пока что. запрос не пустой.
b)Сначала выполняется "beforeSubmit"; Потом идет действие обработчика с которого собственно вызвана форма, синхронно, то есть даже если Ajax сохранит форму, то она все равно улетает в свой обработчик и куда-то редиректит, как в форме указать что только ajax запрос должен работать?
c) И самое главное, как лучше принять данные из формы и обработать? Чтоб все собрать использую serialize(), и в JSON-e отправляю, как это на сервере принять и обработать, с учетом того что мне html нужно вернуть, если succes: вид со всеми товарами, если error: форму с отображенными ерорсами. Кому не лень разъясните или ткните носом где почитать об этом подробней плз, а то с ajax ActiveForm первый раз работаю. Заранее спасибо)

Решение

$script = <<< JS

    $(document).on("beforeSubmit", "#product-form", function () {
    
                //Сама форма    
                var form = $(this);
                $.ajax({
                    //Тип запроса
                    type: form.attr('method'),

                    //Адрес запроса
                    url: form.attr('action'),

                     //Данные из формы в массиве
                    data: form.serializeArray(),
                     }
                 )
                 
                 //Если запрос отправлен
                 .done(function(data) {
                 
                       //Не прошла валидация с сервера 
                      if (data.validation) {
                         form.yiiActiveForm('updateMessages', data.validation, true); // renders validation messages at appropriate places
                     } else {
                        //Рендр полученного шаблона в блок вместо формы(в моем случае список продуктов)
                        jQuery('.my_own_info').html(data);
                        window.history.replaceState('admin', null, '/admin/feed/my-products')
                     }
                 })
        //Если запрос не ушел
        .fail(function () {
           
            alert('Ошибка, попробуйте позже');
        })

    return false; // Отменить синхронную отправку данных
    
    });

JS;
    $this->registerJs($script);

?>


в контроллере:
//Если пришел Ajax запрос
        if (Yii::$app->request->isAjax) {

            //Если объект создан        
            if ($model->load(Yii::$app->request->post()) && $model->save()) {

                //Вернуть нужныйй шаблон хтмл
                $products = Product::find()->all();
                return $this->renderAjax('my_products', compact($products));
            }

            $result = [];
            //если валидация модели не прошла, собираем ошибки, и возвращаем  
            foreach ($model->getErrors() as $attribute => $errors) {
                $result[Html::getInputId($model, $attribute)] = $errors;
            }

            return $this->asJson(['validation' => $result]);

        }
  • Вопрос задан
  • 1373 просмотра
Решения вопроса 1
slo_nik
@slo_nik Куратор тега Yii
Добрый день.
a)Запрос все время возвращается ерорсами

Какими именно?
как в форме указать что только ajax запрос должен работать

В js коде добавьте e.preventDefault(), чтобы отменить действие по умолчанию для формы, в контролере проверяйте, что выполняется именно ajax запрос.
if(Yii::$app->request->isAjax)
{
   // обрабатываете данные.
}

И самое главное, как лучше принять данные из формы и обработать?

Например так:
Раз
Два(раздел AJAX form submission with server validation)
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы