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 ' ';
echo GxHtml::submitButton(Yii::t('app', 'Save: Finalize Edit Day'),array('name'=>'save'));
echo ' ';
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]