Ajax Validation of checkboxes

I have several checkboxes on a CAactiveForm of which the user is only allowed to select two. I have a rule that checks for this.

I am also validating the form via ajax. However it is not triggering when a checkbox’s state changes!

Looking though yiiactiveform.js, it seems to be because the value is always one, regardless of whether is checked or not, and this is what is used to detect a state change.

I added a click event to the checkboxes to change their value, and now the ajax post is triggred, but it is not picking up on the checked status of the changed checkbox

Any help appreciated.

yiiactiveform.js works on jquery.delegate(), it works perfect , if you use




<?php $form = $this->beginWidget('CActiveForm', array(

    'id'=>'user-form',

    'enableAjaxValidation'=>true,

    


)); 


echo $form->errorsummary($model);


?>




Hi Igor

I already have ‘enableAjaxValidation’=>true,

Ajax validation is working fine on other elements, just not checkboxes.

Can you show your form and JavaScript code?

if dosent work try to separate

this will work




$optionNames = array(


		'validationDelay' => '100',

		'validateOnChange' => true,//false

		'validateOnType' => false,//if change false type 'click'

		'hideErrorMessage' => false, //true false

		'inputContainer' => '',//undefined

		'errorCssClass' => 'error_red',//undefined

		'successCssClass' => 'succsed',//undefined

		'validatingCssClass' => 'validate_me',//undefined

		//'beforeValidateAttribute' => ''

		//'afterValidateAttribute' => '',//undefined	

	); 

	

	

echo $form->error($model,'checkboxname',$optionNames,$enableAjaxValidation=true); 

echo $form->error($model,'checkboxname2',$optionNames,$enableAjaxValidation=true);

echo $form->error($model,'checkboxname3',$optionNames,$enableAjaxValidation=true);

echo $form->error($model,'checkboxname4',$optionNames,$enableAjaxValidation=true);  	




Igor, I tried what you suggested, but still no joy.

Here is the form code:







$form = $this->beginWidget('CActiveForm', array(

	'id'=>"offerTypeFieldsForm",

	'enableAjaxValidation'=>true,

));


$optionNames = array(

	'validationDelay' => '100',

	'validateOnChange' => true,//false

	'validateOnType' => false,//if change false type 'click'

	'hideErrorMessage' => false, //true false

	'inputContainer' => '',//undefined

	'errorCssClass' => 'error_red',//undefined

	'successCssClass' => 'succsed',//undefined

	'validatingCssClass' => 'validate_me',//undefined

	//'beforeValidateAttribute' => ''

	//'afterValidateAttribute' => '',//undefined

);


?>


		<div id="offerTypeField" class="form">




				... other form elements


				<div class="row">

					<?php echo $form->labelEx($model,'option1'); ?>

					<?php echo $form->checkbox($model,'option1', $optionNames, $enableAjaxValidation=true); ?>

					<?php echo $form->error($model,'option1'); ?>

				</div>


				<div class="row">

					<?php echo $form->labelEx($model,'option2'); ?>

					<?php echo $form->checkbox($model,'option2', $optionNames, $enableAjaxValidation=true); ?>

					<?php echo $form->error($model,'option2'); ?>

				</div>


... other form elements



$optionNames and $enableAjaxValidation=true should be passed to "error" method, not to "checkbox" one.

Igor, I tried what you suggested, but still no joy.

The form is rather complex, but here is a simplified version that have tested and isn’t working.

If I follow the javascript in firebug then I can see that the reason it is not triggering is because the value is unchanged (The value doesn’t change when a check box is checked; an attribute ‘checked’ is added). Are you sure this works for you.







$form = $this->beginWidget('CActiveForm', array(

	'id'=>"offerTypeFieldsForm",

	'enableAjaxValidation'=>true,

));


$optionNames = array(

	'validationDelay' => '100',

	'validateOnChange' => true,//false

	'validateOnType' => false,//if change false type 'click'

	'hideErrorMessage' => false, //true false

	'inputContainer' => '',//undefined

	'errorCssClass' => 'error_red',//undefined

	'successCssClass' => 'succsed',//undefined

	'validatingCssClass' => 'validate_me',//undefined

	//'beforeValidateAttribute' => ''

	//'afterValidateAttribute' => '',//undefined

);


?>


		<div id="offerTypeField" class="form">




				... other form elements


				<div class="row">

					<?php echo $form->labelEx($model,'option1'); ?>

					<?php echo $form->checkbox($model,'option1', $optionNames, $enableAjaxValidation=true); ?>

					<?php echo $form->error($model,'option1'); ?>

				</div>


				<div class="row">

					<?php echo $form->labelEx($model,'option2'); ?>

					<?php echo $form->checkbox($model,'option2', $optionNames, $enableAjaxValidation=true); ?>

					<?php echo $form->error($model,'option2'); ?>

				</div>


                                ... other form elements

		</div>

<?php $this->endWidget(); ?>



I fixed that, but still not working.

This morning I tried creating a fresh app and I still have exactly the same problem.

I created the model and CRUD using Gii. Then uncommented the ajax validation in the controller, changed ‘enableAjaxValidation’ in the form to true. Changes in the text field trigger validation, but the checkbox does not.

I added the changes suggested by Igor, but still no validation on the checkbox.

Can someone please confirm that they have working ajax validation on checkboxes. I can’t see how it could work after going through the JavaScript file.

Alternatively is there a way I can manually trigger validation using javascript. I’ve tried changing the value in a click event and while this triggers validation it does not pick up the ‘checked’ value in the POST values. If I then change the text box to trigger a second validation it does pick up the change.

here is the form code




<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'offer-type-field-form',

	'enableAjaxValidation'=>true,

));




$optionNames = array(

        'validationDelay' => '100',

        'validateOnChange' => true,//false

        'validateOnType' => false,//if change false type 'click'

        'hideErrorMessage' => false, //true false

        'inputContainer' => '',//undefined

        'errorCssClass' => 'error_red',//undefined

        'successCssClass' => 'succsed',//undefined

        'validatingCssClass' => 'validate_me',//undefined

        //'beforeValidateAttribute' => ''

        //'afterValidateAttribute' => '',//undefined

);


?>


	<p class="note">Fields with <span class="required">*</span> are required.</p>


	<?php echo $form->errorSummary($model); ?>


	<div class="row">

		<?php echo $form->labelEx($model,'label'); ?>

		<?php echo $form->textField($model,'label',array('size'=>60,'maxlength'=>256)); ?>

		<?php echo $form->error($model,'label'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'is_label_link'); ?>

		<?php echo $form->checkbox($model,'is_label_link'); ?>

		<?php echo $form->error($model,'is_label_link', $optionNames, $enableAjaxValidation=true); ?>

	</div>


	<div class="row buttons">

		<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>

	</div>


<?php $this->endWidget(); ?>


</div><!-- form -->



I’ve managed to make my workaround work.

You have to update the value of the hidden field that is connected to the checkbox as well. It has the same name as the checkbox but starts with yt.

EG: If I add this javascript to the page for each checkbox then the form is being posted back. I havn’t checked yet if errors are displayed.




$("#ModelName_fieldName").click(function(e){

	if($(this).val() == "1"){

		$(this).val("0");

		$("#ytModelName_fieldName").val("0");

	}else{

		$(this).val("1");

		$("#ytModelName_fieldName").val("1");

	}

});



Another problem.

If the checkbox is unchecked when the page first loads then the value is set to 1. So that JavaScript above sets it the wrong way.

I’ve tried adding the following to set the value




<?php echo $form->checkbox($model,'is_label_link', array("value"=>$model->is_label_link)); ?>



However for some odd reason whatever I change ‘value’ to, Yii decides to add a ‘checked’ attribute. (Even though the default value is “1” and checked is not set).

The solution is to set value to "" and not "0".




<?php echo $form->checkbox($model,'is_label_link', array("value"=>$model->is_label_link == 1 ? "1" : "")); ?>