Yii - Triggering Validation of an Individual Input/Element Manually with Javascript

Yii - Triggering Validation of an Individual Input/Element Manually with Javascript

Last updated:

The need to programatically trigger validation of an individual CActiveForm element comes to me somewhat often. Forms sometimes turns out to be the most complex parts of an application and we always need custom behaviour.

This is the second time I've needed to do this so I reckoned I would do a little bit of research into how to do it "The Yii Way" (and write about it, for many others probably have the same issues).

I confess I knew about these javascript functions (like those under $.fn.yiiactiveform and $.fn.yiigridview and so on) but never quite took the time to understand them.

I have a form that governs the generation of a PDF report. There is an input field called "report_name" and a checkbox called "save_in_history". My problem is that I would like an error message (red, under 'report_name' text input) to be shown (immediately) if a user checked 'save_in_history' checkbox while the 'report_name' input is empty.

The following code illustrates how one should create a javascript callback that gets run after any element gets validated via ajax. The code is self-explanatory and I've added comments to help clarify the objectives:

<?php
$form = $this->beginWidget('CActiveForm', [
    'id' => 'pdf-report-form',
    'enableAjaxValidation' => true,
    'enableClientValidation' => true,
    'clientOptions' => [
        'validateOnSubmit' => true,
        'afterValidateAttribute' => 'js:function(form, attribute, data, hasError)
         {

            //I want this to run if the checkbox is checked
            if (attribute.name === "save_in_history"){
                //all form information is here
                var settings = $.fn.yiiactiveform.getSettings(form); 

                    //cycling through ethe attributes
                    $.each(settings.attributes, function () {
                        if (this.name === "report_name") {
                            //trigger validation on the other element
                            $.fn.yiiactiveform.updateInput(this, data, form); 
                        }
                    });

                    //keep things consistent with normal Yii code
                    $.fn.yiiactiveform.updateSummary(form,data);
            }
        }'
]]);

Dialogue & Discussion