Ajax валидация и сохраниение формы не срабатывает

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
andrej3337
Сообщения: 46
Зарегистрирован: 2019.11.03, 16:02

Ajax валидация и сохраниение формы не срабатывает

Сообщение andrej3337 »

Здравствуйте.
Много чего перерыл, но из найденных примеров у меня не работает. Валидация срабатывает, ошибки показывает, но данные из формы не приходят и не сохраняются.

Цель - когда пользователь заполняет форму, если все нормально, появляется кнопка загрузки документа, получает вордовский документ. Жать кнопку отправки формы не нужно
Форма

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

    <?php $form = ActiveForm::begin([
        'enableClientValidation' => true,
        'enableAjaxValidation' => true,
        'action' => Url::toRoute('/perevod-default/update?id='.$model->id),
        'validationUrl' => Url::toRoute('/perevod-default/ajax'),
        'options' => ['class' => 'perevod-default-form','id' => $model->formName() ]
  ]); ?>
Стандартный экшн из контролера, сгенерированного gii CRUD, правда мною замученный

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

    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        $session = Yii::$app->session;
        $session->open();
        $session['id'] = $model->id;
        $session->close();
        if (\Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()) && $model->validate() && $model->save()) {
            Yii::$app->response->format = Response::FORMAT_JSON;
                return $this->renderAjax('update', [
                    'model' => $model,
                ]);
        }
        return $this->render('update', [
            'model' => $model,
        ]);
    }
Добавлен экшн для аякс валидации

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

    public function actionAjax() {
        $model = new PerevodDefault();
        if (Yii::$app->request->isAjax ) {
            Yii::$app->response->format = Response::FORMAT_JSON;
            if ($model->load(Yii::$app->request->post())) {
                return ActiveForm::validate($model);
            }
        }
        throw new \yii\web\BadRequestHttpException('Bad request!');
    }
Скрипт

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

$js ="
   $(document).ready(function () { 
        $('#{$model->formName()}').on('beforeSubmit', function (event) { 
            event.preventDefault();            
            var form_data = new FormData($('#{$model->formName()}'));
            $.ajax({
                   url: $('#{$model->formName()}').attr('action'),
                   dataType: 'JSON',  
                   cache: false,
                   contentType: false,
                   processData: false,
                   data: form_data.serialize(),                  
                   type: 'post',                        
                   beforeSend: function() {
},
                   success: function(response){
    toastr.success(' ',response.message);
},
                   complete: function() {
},
                   error: function (data) {
    toastr.warning(' ','There may a error on uploading. Try again later');
}
                });                
            return false;
        });
    });       
                ";
$this->registerJs($js);
Аватара пользователя
leonenco
Сообщения: 155
Зарегистрирован: 2017.01.30, 22:42

Re: Ajax валидация и сохраниение формы не срабатывает

Сообщение leonenco »

andrej3337 писал(а): 2021.01.07, 15:08 Здравствуйте.
Много чего перерыл, но из найденных примеров у меня не работает. Валидация срабатывает, ошибки показывает, но данные из формы не приходят и не сохраняются.

Цель - когда пользователь заполняет форму, если все нормально, появляется кнопка загрузки документа, получает вордовский документ. Жать кнопку отправки формы не нужно
Форма

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

    <?php $form = ActiveForm::begin([
        'enableClientValidation' => true,
        'enableAjaxValidation' => true,
        'action' => Url::toRoute('/perevod-default/update?id='.$model->id),
        'validationUrl' => Url::toRoute('/perevod-default/ajax'),
        'options' => ['class' => 'perevod-default-form','id' => $model->formName() ]
  ]); ?>
Стандартный экшн из контролера, сгенерированного gii CRUD, правда мною замученный

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

    public function actionUpdate($id)
    {
        $model = $this->findModel($id);
        $session = Yii::$app->session;
        $session->open();
        $session['id'] = $model->id;
        $session->close();
        if (\Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()) && $model->validate() && $model->save()) {
            Yii::$app->response->format = Response::FORMAT_JSON;
                return $this->renderAjax('update', [
                    'model' => $model,
                ]);
        }
        return $this->render('update', [
            'model' => $model,
        ]);
    }
Добавлен экшн для аякс валидации

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

    public function actionAjax() {
        $model = new PerevodDefault();
        if (Yii::$app->request->isAjax ) {
            Yii::$app->response->format = Response::FORMAT_JSON;
            if ($model->load(Yii::$app->request->post())) {
                return ActiveForm::validate($model);
            }
        }
        throw new \yii\web\BadRequestHttpException('Bad request!');
    }
Скрипт

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

$js ="
   $(document).ready(function () { 
        $('#{$model->formName()}').on('beforeSubmit', function (event) { 
            event.preventDefault();            
            var form_data = new FormData($('#{$model->formName()}'));
            $.ajax({
                   url: $('#{$model->formName()}').attr('action'),
                   dataType: 'JSON',  
                   cache: false,
                   contentType: false,
                   processData: false,
                   data: form_data.serialize(),                  
                   type: 'post',                        
                   beforeSend: function() {
},
                   success: function(response){
    toastr.success(' ',response.message);
},
                   complete: function() {
},
                   error: function (data) {
    toastr.warning(' ','There may a error on uploading. Try again later');
}
                });                
            return false;
        });
    });       
                ";
$this->registerJs($js);
Ваш акшион ждет `GET request` c ID что фактически не происходит, так как вы отправляете Аякс через POST.

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

public function actionUpdate($id)<-----
Что вам нужно сделать - это проверить если POST запрос содержит необходимый вам параметер. а затем я думаю что ваш процесс заработает. Удачи.
andrej3337
Сообщения: 46
Зарегистрирован: 2019.11.03, 16:02

Re: Ajax валидация и сохраниение формы не срабатывает

Сообщение andrej3337 »

Что за чертовщина?
Видоизменил аякс урл и соответственно экшн, так модель сохраняется

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

    public function actionAjax($id) {
        $model = $this->findModel($id);
        if (Yii::$app->request->isAjax || Yii::$app->request->isPjax) {
            \Yii::$app->response->format = Response::FORMAT_JSON;
            if ($model->load(Yii::$app->request->post())) {
                $model->save();
            }
        } else {
             throw new HttpException('403', 'Access Denied');
        }
    }
То же самое, только с аякс валидацией в случае ошибки, но модель не сохраняется, при этом в случае ошибки валидация срабатывает. Это же элементарное иф/елсе, должно срабатывать или одно, или второе

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

public function actionAjax($id) {
        $model = $this->findModel($id);
        if (Yii::$app->request->isAjax || Yii::$app->request->isPjax) {
            \Yii::$app->response->format = Response::FORMAT_JSON;
            if ($model->load(Yii::$app->request->post())) {
               if (!$model->getErrors()) {
                   return ActiveForm::validate($model);
                } else{
                   $model->save();
                }
            }
        } else {
             throw new HttpException('403', 'Access Denied');
        }
    }
Аватара пользователя
maleks
Сообщения: 1992
Зарегистрирован: 2012.12.26, 12:56

Re: Ajax валидация и сохраниение формы не срабатывает

Сообщение maleks »

Во втором коде у вас проблемы с логикой
- вы грузите данные через load
- вы проверяете if (!$model->getErrors()) , а это всегда будет истина, вы же не запускали валидацию до него
andrej3337
Сообщения: 46
Зарегистрирован: 2019.11.03, 16:02

Re: Ajax валидация и сохраниение формы не срабатывает

Сообщение andrej3337 »

Вроде заработало как задумано.

Форму изменил

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

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

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

    public function actionUpdate($id)
    {
        $model = PerevodDefault::findOne($id);
        $session = Yii::$app->session;
        $session->open();
        if (\Yii::$app->request->isAjax) {
            \Yii::$app->response->format = Response::FORMAT_JSON;
            if ($model->load(Yii::$app->request->post())) {
                if (!empty(ActiveForm::validate($model))) {
                    return ActiveForm::validate($model);
                } else{
                    return ['success' => $model->save()];
                }
            }
        }
        $session['id'] = $model->id;
        $session->close();
        return $this->render('update', [
            'model' => $model,
        ]);
    }

Удалил validationUrl, а то с ним срабатывал только конкретный указанный в нем экшн, а без него и actionCreate, и actionUpdate($id) передают данные аяксом. Ну и понятно actionAjax($id) удалил. Т.е. стандартная (почти) схема CRUD работает.
Ответить