Working with ActiveForm via JavaScript

PHP side of ActiveForm, which is usually more than enough for majority of projects, is described well in the official Yii 2.0 guide. It is getting a bit more tricky when it comes to advanced things such as adding or removing form fields dynamically or triggering individual field validation using unusual conditions.

In this recipe you'll be introduced to ActiveForm JavaScript API.

Preparations

We're going to use basic project template contact form for trying things out so install it first.

Triggering validation for individual form fields

$('#contact-form').yiiActiveForm('validateAttribute', 'contactform-name');

Trigger validation for the whole form

$('#contact-form').yiiActiveForm('validate', true);

The second passed argument true forces validation of the whole form.

Using events

$('#contact-form').on('beforeSubmit', function (e) {
    if (!confirm("Everything is correct. Submit?")) {
        return false;
    }
    return true;
});

Available events are:

Adding and removing fields dynamically

To add a field to validation list:

$('#contact-form').yiiActiveForm('add', {
    id: 'address',
    name: 'address',
    container: '.field-address',
    input: '#address',
    error: '.help-block',
    validate:  function (attribute, value, messages, deferred, $form) {
        yii.validation.required(value, messages, {message: "Validation Message Here"});
    }
});

To remove a field so it's not validated:

$('#contact-form').yiiActiveForm('remove', 'address');

Updating error of a single attribute

In order to add error to the attribute:

$('#contact-form').yiiActiveForm('updateAttribute', 'contactform-subject', ["I have an error..."]);

In order to remove it:

$('#contact-form').yiiActiveForm('updateAttribute', 'contactform-subject', '');

Update error messages and, optionally, summary

$('#contact-form').yiiActiveForm('updateMessages', {
    'contactform-subject': ['Really?'],
    'contactform-email': ['I don\'t like it!']
}, true);

The last argument in the above code indicates if we need to update summary.

Listening for attribute changes

To attach events to attribute changes like Select, Radio Buttons, etc.. you can use the following code

$("#attribute-id").on('change.yii',function(){
        //your code here
});

Getting Attribute Value

In order to be compatible with third party widgets like (Kartik), the best option to retrieve the actual value of an attribute is:

$('#form_id').yiiActiveForm('find', '#attribute').value

Custom Validation

In case you want to change the validation of an attribute in JS based on a new condition, you can do it with the rule property whenClient, but in the case you need a validation that doesn't depends on rules (only client side), you can try this:

$('#form_id').on('beforeValidate', function (e) {
            $('#form_id').yiiActiveForm('find', '#attribute').validate = function (attribute, value, messages, deferred, $form) {
                //Custom Validation
            }
        return true;
    });