Yii2: ActiveForm: ability to use AJAX on submit only

Created on 7 Apr 2014  路  31Comments  路  Source: yiisoft/yii2

how to add validation errors manually?

Example:

<?php $form = ActiveForm::begin([
    'id' => 'frm-login',
    'action' => ['login'],  
    'beforeSubmit' => "function(form) {
        var form = $(form);                                 
        if(form.find('.has-error').length) {
            return false;
        }                               
        $.ajax({
            url: form.attr('action'),
            type: 'post',
            data: form.serialize(),
            success: function(response) {                                       
                console.log(response);
                updateSummary(form, response);
            }
       });                              
       return false;
    }" ]); ?>                       

      <div class="alert alert-danger error-summary">                                            
      </div>

      <?= $form->field($login, 'username') ?>                           
      <?= $form->field($login, 'password')->passwordInput() ?>                                                      
      <?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>                                              
<?php ActiveForm::end(); ?>
form docs enhancement

Most helpful comment

@qiangxue this way works

<?php $form = ActiveForm::begin([
    'enableAjaxValidation' => true,
    'validateOnChange' => false
]); ?>

but client validation could be onchange

All 31 comments

Is this a question, or bug report? What is the issue?

it is a question.

this code not works.

 success: function(response) {                                       
    console.log(response);
    updateSummary(form, response);// error
}

what kind of error? Please provide detailed information.

The method updateSummary is not available to use external of yiiActiveForm plugin.

I would know if you can make this method available

this is the original error:

Uncaught ReferenceError: updateSummary is not defined 

I see wha you mean, you are trying to update the summary yourself but you cannot because of: https://github.com/yiisoft/yii2/blob/master/framework/assets/yii.activeForm.js#L372

It needs to be in the methods property

May be related #1422

Kind of though that is to do with rules rather than updating the summary

@leandrogehlen what are you trying to achieve?

currently, validation errors are returned on blur of inputs.

I would like that return a unique time when i submit the form.

so, is necessary to add validation errors in the inputs or summary.

my suggestion is create two methods property:

updateSummary(errors) and updateInput(id, errors)

Would disabling clientside validatior work for you? i.e. it will do exactly what you want (well, maybe except actually submitting a form).

It works, but, how to show remote errors like ActiveForm does?

What do you mean by "remote errors"?

Validation errors returned by ajax

You need to specify parameters for the form like the following:

<?php $form = ActiveForm::begin([
    'enableClientValidation' => false,
    'enableAjaxValidation' => true,

Ok, but i would like to avoid many ajaxRequest.
I would like to return all errors on subimit and display all errors

Then

<?php $form = ActiveForm::begin([
    'enableClientValidation' => false,
    'enableAjaxValidation' => false,

and it will just validate serverside once when form is submitted.

but just does not work submit by ajax

So you want it to make only one AJAX request only when hitting submit button and not do any validation till the button is pressed?

exactly

You can configure validateOnChange to be false for the field.

Can be done for the whole form as well.

Since these are quite common questions I'll check how to better add it to the guide.

It would be interesting to work with the two forms together.

  • client validation - validate onchange of input
  • ajax validation - validate on submit

@qiangxue this way works

<?php $form = ActiveForm::begin([
    'enableAjaxValidation' => true,
    'validateOnChange' => false
]); ?>

but client validation could be onchange

I would like to set an example:

class User extends ActiveRecord{

    public function rules()
    {
          return [
               [['email','password'], 'required'],
               ['email', 'unique'],
         ]
    }
}
  • required could be validated in change event (is a client validation)
  • unique could be validated in submit event (is a remote validation)

this means that i have two type of validation at the same time

It makes sense. We will consider this for RC.

@qiangxue isn't it settable per field already?

@samdark Yes, but the setting affects both ajax validation and non-ajax js validation, while @leandrogehlen wants to separate these two kinds of validations further.

the dialog between samdark and leandrogehlen is a perfect guideline already if you noticed. LOL
Probably, we can have more examples like: Capcha need ajaxValidation to be false, will fail if turn it on, and why. things like that.

Moved to 2.0.1 since this is not a critical issue.

I am also facing problem regarding manually adding error msgs to form. In my case I don't have any problem with ajax validation. I have two scenarios in rules. one is 'default' and one is 'login' like this

public function rules() {
    return [
      // email and password are both required
      [['email', 'password' ], 'required' ],
      ['email', 'email' ],
      // email is validated by validateEmail()
      ['email', 'validateEmail', 'on' => 'login' ],
      // password is validated by validatePassword()
      ['password', 'validatePassword', 'on' => 'login' ],
    ];
  }

I am using default scenario for ajax validation on blur and change and it is being handled fine with ajax validation. The problem is with 'login' scenario, I want to validate using 'login' scenario only when user clicks on submit button. To achieve this I attached 'beforeSubmit' event like this

$('body').on('beforeSubmit', 'form#loginForm', function() {
    var form = $(this);
    if (form.find('.has-error').length) {
      return false;
    }

    $.ajax({
      url: form.attr('action'),
      type: 'post',
      data: form.serialize(),
      success: function(errors) {
        // How to update form with error messages?
      }
    });

    return false;
  });

Now above event is working fine and it sends the ajax request to server when user clicks on submit button and I validate the fields with 'login' scenario and return the errors in json if there are any otherwise redirect the user to some other page.

Now the problem is if I get validation errors in return at this point I can not show those errors in form to user using yii.activeForm.js, because updateInputs is not accessible publicly. Or is there another way to update the form error messages manually?

And the reason I have this 'login' scenario is because I want to validate email and password together in database only when user clicks on submit button.

Was this page helpful?
0 / 5 - 0 ratings