1
votes

Using the beforeSubmit function of yii.activeForm.js, how can I make it perform a normal form submit when validation passes?

I have tried the following:

$('.ajax-form').on('beforeSubmit', function (event) {
    var form = $(this);
    var url = form.attr('action');
    var type = form.attr('method');
    var data = form.serialize();

    $.ajax({
        url: url,
        type: type,
        data: data,
        success: function (result) {
            if (result.errors.length != 0) {
                form.yiiActiveForm('updateMessages', result.errors, true);
            }
            else if (result.confirmed == true) {
                $('.confirm-panel').show();
            }
            else {
                return true;
            }
       },
       error: function() {
           alert('Error');
       }
    });

    // prevent default form submission
    return false;
});

Controller:

public function actionProcess()
{
    $model = $this->findModel($id);

    if (Yii::$app->request->isAjax) {
        $return_array = [
            'errors' => [],
            'confirmed' => false,
        ];

        Yii::$app->response->format = Response::FORMAT_JSON;
        $return_array['errors'] = ActiveForm::validate($model);

        if ($model->confirm == 1) {
            $return_array['confirmed'] = true;
        }

        return $this->asJson($return_array);
    }

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['success']);
    }

    return $this->render('process', [
        'model' => $model,
    ]);
}

As you can see I am also trying to return additional data in my AJAX response. The problem I am having is the return true in the ajax success isn't working. I can't seem to break out of the function. I have also tried form.submit() here but this just does a submit loop via AJAX.

By the way I am not using enableAjaxValidation because I have some additional custom validation that happens in my controller. So this is why I have created my own custom handler for this.

3
you cannot return true from the ajax readystate and why are you trying to send an ajax call to validate the form when yii provide you the option enableAjaxValidation and what are your custom validation methods that cannot be adjusted into the model and triggered via ajax ? you should add the code for your form view and controller action - Muhammad Omer Aslam
@MuhammadOmerAslam when the form is submitted (via ajax) it needs to return some custom html if validation passes, I have not been able to work out how to do this with enableAjaxValidation. - MAX POWER
well if you can share we can sort it out if you like. - Muhammad Omer Aslam
@MuhammadOmerAslam - added controller action code. - MAX POWER

3 Answers

1
votes

First of all, you can't return true from within an ajax success function to continue form submission as it is javascript and the last line return true is already executed before the response is received so the form ain't going to submit by returning true inside the success function.

You need to use the event afterValidate if you want to submit your page manually after successful ajax validation rather than using beforeSubmit as it will go into an infinite loop if you try to submit the form using $("form").submit() inside the ajax success function. so change your line

$('.ajax-form').on('beforeSubmit', function (event) {

to

$('.ajax-form').on('afterValidate', function (event) {

and then change your success function to

success: function (result) {
            if (result.errors.length != 0) {
                form.yiiActiveForm('updateMessages', result.errors, true);
            }
            else if (result.confirmed == true) {
                $('.confirm-panel').show();
            }
            else {
                form.submit();
            }
       },

Hope it helps you out.

0
votes

Input validation should be made in models no matter if it's built in or custom. Then you can easily use the default ajax validation.

For creating custom validators check http://www.yiiframework.com/doc-2.0/guide-input-validation.html#creating-validators

0
votes

you need not to write any such code for this propose. Yii can handle ajax validations it-self. only thing that you need to do is enable it in active form like.

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

and placing this code in controller after initialize $model.

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