Validate Two Fields At The Same Time

Hello!

Searching a good solution to "One common validation test for multiple attributes" I found that post.

How to solve that: create a new attribute to handle multiple attributes by its rule.

Problem or imperfection: don’t validate the attributes contained in the new attribute when the AjaxValidation is executed and only validate when the button submit is clicked.

This is the structure:


//new attribute

    	public $selectionGroup;


//new rule

   	array('selectionGroup', 'validateGroup'),


//method of rule

  	public function validateGroup($attribute)

  	{

            	if (!$this->is_visit && !$this->is_booking)

            	{

                    	$this->addError('is_visit',null);      	//without message only mark label in red

                    	$this->addError('is_booking',null);	//same prior

                    	$this->addError($attribute,'Check at least one of the following attributes: visit or booking.'); 	//message

            	}

            	return true;

	}

How do to make to validation ajax worked when the attributes -contained- changed?

Thanks for helping.

I find the problem, but I don’t understand the reason…

I use a form with multiple models and ajax Validation is not working correctly, because only validate one model (called Timetable) and skip rest models.

This occur because the flow is broken in the following point of model (see more below also):


...if($modelTimetable->validate())

So, this does that form show only errors for one model.

// model


<?php

Yii::import('application.models._base.BaseTimetable');


class Timetable extends BaseTimetable

{

    	public $selectionGroup;

	

	public static function model($className=__CLASS__) {

		return parent::model($className);

	}


	public function rules() {

		return array(

        	array('is_recommendation, is_visit, is_booking', 'required'),

			array('is_recommendation, is_visit, is_booking', 'numerical', 'integerOnly'=>true),


        	array('is_booking', 'validateGroup'),


 			array('id_timetable, id_day, is_recommendation, is_visit,  is_booking, dateCreated, dateModified', 'safe', 'on'=>'search'),

		);

	}


    	public function beforeSave() {

        	if ($this->isNewRecord)

            	$this->dateCreated = new CDbExpression('NOW()');


        	$this->dateModified = new CDbExpression('NOW()');


        	return parent::beforeSave();

    	}

    	public function validateGroup($attribute)

 		{

            	if (!$this->is_visit && !$this->is_booking)

            	{

                    	$this->addError('is_visit', null);

                    	$this->addError('is_booking', null);

 						$this->addError('selectionGroup', 'Check at least one of the  following attributes: visit or booking.');

            	}

            	return true;

    	}

}  

// controller


$this->performAjaxValidation(

                    	array($modelTimetableLanguage, 	

                          	$modelTimetable, 			

                          	$modelRecommendation,

                          	//$modelVisit,

                          	$modelBooking,

                          	$modelBookingLanguage),

                    	'timetable-form');


            	if(isset($_POST['back']))

            	{

                    	Yii::app()->msg->postMsg('note', 'Create Day process canceled: day will not save.');

                    	Yii::app()->msg->saveMsg();

                    	$this->render('view_update_day', array('model' => $model,'code' => $codeLanguage,'modelDayLanguage' => $modelDayLanguage,));

            	}

            	if (isset($_POST['TimetableLanguage'], $_POST['Timetable'], $_POST['Recommendation'], 

                      	//$_POST['Visit'], 

                      	$_POST['Booking'], $_POST['BookingLanguage']))

            	{

                    	if (isset($_POST['save']))

                    	{

                            	Yii::trace($_POST['TimetableLanguage'], 'timetableLanguage');

                            	Yii::trace($_POST['Timetable'], 'timetable');


                            	if (isset($_POST['TimetableLanguage'], 

                                      	$_POST['Timetable'],

                                      	$_POST['Recommendation'], 

                                      	//$_POST['Visit'], 

                                      	$_POST['Booking'],

                                      	$_POST['BookingLanguage']))

                            	{

                                    	//Recuperamos datos del formulario

                                    	$modelTimetable->setAttributes($_POST['Timetable']);


                                    	//Informamos los campos no públicos

                                    	$modelTimetable->id_day = $modelDay->getId_Day();

                                    	

                                    	Yii::trace($modelTimetable->validate(), 'timetableValidate');

// point break controller flow


                           				if($modelTimetable->validate())

// form


<div class="form">


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

	'id' => 'timetable-form',

	'enableAjaxValidation' => true,

    	//'clientOptions'=>array('validateOnSubmit'=>false, 'hideErrorMessage'=>true),

    	'focus' => array($modelTimetableLanguage, 'car_route'),

));

?>

	

<?php Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl.'/protected/javascript/dinamicTimetable.js',CClientScript::POS_END);?>


	<p class="note">

		<?php echo Yii::t('app', 'Fields with'); ?> <span class="required">*</span> <?php echo Yii::t('app', 'are required'); ?>.

	</p>


	<?php echo $form->errorSummary(array($modelTimetableLanguage,$modelTimetable,$modelRecommendation,$modelBooking,$modelBookingLanguage)); ?>


            	<!-- GENERAL FIELDS: $modelTimetableLanguage - PART I -->

            	<div class="row">

		<?php echo $form->labelEx($modelTimetableLanguage,'car_route'); ?>

		<?php echo $form->textArea($modelTimetableLanguage, 'car_route', array('maxlength' => 255,'style'=>'width: 350px; height: 20px')); ?>

		<?php echo $form->error($modelTimetableLanguage,'car_route'); ?>

            	</div><!-- row -->

            	<div class="row">

		<?php echo $form->labelEx($modelTimetableLanguage,'link_gmaps'); ?>

		<?php echo $form->textArea($modelTimetableLanguage, 'link_gmaps', array('maxlength' => 65535,'style'=>'width: 700px; height: 180px')); ?>

		<?php echo $form->error($modelTimetableLanguage,'link_gmaps'); ?>

            	</div><!-- row -->

            	<div class="row">

		<?php echo $form->labelEx($modelTimetableLanguage,'distance'); ?>

		<?php echo $form->dropDownList($modelTimetableLanguage, 'distance', range(TimetableLanguage::MIN_DISTANCE,TimetableLanguage::MAX_DISTANCE));?>

		<?php echo $form->error($modelTimetableLanguage,'distance'); ?>

            	</div><!-- row -->

            	<div class="row">

		<?php echo $form->labelEx($modelTimetableLanguage,'hours'); ?>

		<?php echo $form->dropDownList($modelTimetableLanguage, 'hours', range(TimetableLanguage::MIN_HOURS,TimetableLanguage::MAX_HOURS));?>

		<?php echo $form->error($modelTimetableLanguage,'hours'); ?>

            	</div><!-- row -->

            	<div class="row">

		<?php echo $form->labelEx($modelTimetableLanguage,'minutes'); ?>

		<?php echo $form->dropDownList($modelTimetableLanguage, 'minutes', range(TimetableLanguage::MIN_MINUTES,TimetableLanguage::MAX_MINUTES));?>

		<?php echo $form->error($modelTimetableLanguage,'minutes'); ?>

            	</div><!-- row -->

            	

            	<!-- GENERAL FIELDS: $modelTimetable - PART II -->

		<div class="row">

		<?php echo $form->labelEx($modelTimetable,'is_recommendation'); ?>

		<?php echo $form->checkBox($modelTimetable, 'is_recommendation'); ?>

		<?php echo $form->error($modelTimetable,'is_recommendation'); ?>

            	<!-- RECOMMENDATION FIELDS: $modelRecommendation - PART III -->

                	<div class="row" style="display:none" id="recommendationFields">

                    	<div class="row">

                    	<?php echo $form->labelEx($modelRecommendation,'arrive_on_time'); ?>

                    	<?php $form->widget( 'ext.EJuiTimePicker.EJuiTimePicker', array(

                        	'model' => $modelRecommendation, // Your model

                        	'attribute' => 'arrive_on_time', // Attribute for input

                        	'mode'=>'time',

                        	'options'=>array(

                            	'timeHtmlOptions' => array(

                                	'size' => 5,

                                	'maxlength' => 5,

                            	),

                        	),

                        	'htmlOptions' => array('style' => 'width: 48px; height: 18px'),

                      	)); ?>

                    	<?php echo $form->error($modelRecommendation,'arrive_on_time'); ?>

                    	</div><!-- row -->

                    	<div class="row">

                    	<?php echo $form->labelEx($modelRecommendation,'place'); ?>

                    	<?php echo $form->textArea($modelRecommendation,'place', array('maxlength' => 65535,'style'=>'width: 300px; height: 20px;')); ?>

                    	<?php echo $form->error($modelRecommendation,'place'); ?>

                    	</div><!-- row -->

                	</div>

		</div><!-- row -->

            	

            	<!-- GENERAL FIELDS: $modelTimetable - PART II -->

            	<div class="row">

                    	<div class="row">

                    	<?php echo $form->labelEx($modelTimetable,'is_visit'); ?>

                    	<?php echo $form->checkBox($modelTimetable, 'is_visit'); ?>

                    	<!--?php echo $form->error($modelTimetable,'is_visit'); ?-->

                    	</div><!-- row -->


                    	<!-- GENERAL FIELDS: $modelTimetable - PART II -->

                    	<div class="row">

                    	<?php echo $form->labelEx($modelTimetable,'is_booking'); ?>

                    	<?php echo $form->checkBox($modelTimetable, 'is_booking'); ?>

                    	<!--?php echo $form->error($modelTimetable,'is_booking'); ?-->

                        	<!-- BOOKING FIELDS: $modelBooking, $modelBookingLanguage - PART III -->

                        	<div class="row" style="display:none" id="bookingFields">

                            	<!-- BOOKING GENERAL: $modelBooking - PART III -->

                            	<div class="row">

                            	<?php echo $form->labelEx($modelBooking,'id_kind_booking'); ?>

                            	<!--?php echo $form->dropDownList($modelBooking,'id_kind_booking', GxHtml::listDataEx(KindBookingLanguage::model()->with('id_')->findAll(null, true))); ?-->

                            	<?php echo $form->dropDownList($modelBooking,'id_kind_booking', GxHtml::listDataEx(KindBookingLanguage::listDataActionsLanguages($code),'id_kind_booking','name_action')); ?>

                            	<?php echo $form->error($modelBooking,'id_kind_booking'); ?>

                            	</div><!-- row -->

                            	<div class="row">

                            	<?php echo $form->labelEx($modelBooking,'phone'); ?>

                            	<?php echo $form->textArea($modelBooking,'phone', array('maxlength' => 45,'style'=>'width: 100px; height: 20px;')); ?>

                            	<?php echo $form->error($modelBooking,'phone'); ?>

                            	</div><!-- row -->

                            	<!-- BOOKING SPECIFIC: $modelBookingLanguage - PART IV -->

                            	<div class="row">

                            	<?php echo $form->labelEx($modelBookingLanguage,'details'); ?>

                            	<?php echo $form->textArea($modelBookingLanguage,'details', array('maxlength' => 255,'style'=>'width: 300px; height: 40px;')); ?>

                            	<?php echo $form->error($modelBookingLanguage,'details'); ?>

                            	</div><!-- row -->

                            	<div class="row">

                            	<?php echo $form->labelEx($modelBookingLanguage,'contact'); ?>

                            	<?php echo $form->textArea($modelBookingLanguage,'contact', array('maxlength' => 45,'style'=>'width: 180px; height: 20px;')); ?>

                            	<?php echo $form->error($modelBookingLanguage,'contact'); ?>

                            	</div><!-- row -->

                            	<div class="row">

                            	<?php echo $form->labelEx($modelBookingLanguage,'procedure'); ?>

                            	<?php echo $form->textArea($modelBookingLanguage,'procedure', array('maxlength' => 45,'style'=>'width: 300px; height: 20px;')); ?>

                            	<?php echo $form->error($modelBookingLanguage,'procedure'); ?>

                            	</div><!-- row -->

                        	</div>

                    	</div>

            	<?php echo $form->error($modelTimetable,'selectionGroup') ?>

		</div><!-- row -->


            	<!-- GENERAL FIELDS: $modelTimetableLanguage - PART III -->


<?php

echo GxHtml::submitButton(Yii::t('app', 'Back'),array('name'=>'back'));

echo '&nbsp;&nbsp;&nbsp;';

echo GxHtml::submitButton(Yii::t('app', 'Save:   Finalize Edit Day'),array('name'=>'save'));

echo '&nbsp;&nbsp;&nbsp;';

echo GxHtml::submitButton(Yii::t('app', 'Continue:   New Timetable'),array('name'=>'continue'));

$this->endWidget();

?>

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

To understand better…

…the images: ‘beforeSubmit’ and after submit ‘submitFailAjaxValidation’ show how only is seeing this rules error:


array('is_booking', 'validateGroup'),

Image beforeSubmit:

Image [b]submitFailAjaxValidation:

[/b]