ajaxValidation with multiple models and one form

I’m struggling with ajax validation. I have two models namely acl and user. Each have there own set of validation rules. I however use all input fields within one form.

My form looks as follows


<div class="form">


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

	'id'=>'user-form',

	'enableAjaxValidation'=>true,

	

)); ?>


	<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,'region_id'); ?>

		<?php echo $form->textField($model,'region_id'); ?>

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

	</div>

	

	<div class="row">

		<?php echo $form->labelEx($acl,'userName'); ?>

		<?php echo $form->textField($acl,'userName',array('size'=>20,'maxlength'=>25)); ?>

		<?php echo $form->error($acl,'userName'); ?>

	</div>

	

	<div class="row">

		<?php echo $form->labelEx($acl,'passWord'); ?>

		<?php echo $form->textField($acl,'passWord',array('size'=>20,'maxlength'=>25)); ?>

		<?php echo $form->error($acl,'passWord'); ?>

	</div>

	

	<div class="row">

		<?php echo $form->labelEx($acl,'type'); ?>

		<?php echo $form->textField($acl,'type',array('size'=>20,'maxlength'=>25)); ?>

		<?php echo $form->error($acl,'type'); ?>

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'name',array('size'=>20,'maxlength'=>25)); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'surName',array('size'=>20,'maxlength'=>30)); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'email',array('size'=>20,'maxlength'=>150)); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'email2',array('size'=>20,'maxlength'=>150)); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'cell'); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'tel'); ?>

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

	</div>


	<div class="row">

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

		<?php echo $form->textField($model,'fax'); ?>

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

	</div>


	


	<div class="row buttons">

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

	</div>


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


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

In the UserController I have two ajax validation methods within the createAction method

This looks like this


public function actionCreate()

	{

		$model=new user;

		$acl = new acl;

		

	

		// Uncomment the following line if AJAX validation is needed

	

			$this->performAjaxValidation1($acl);

		

			$this->performAjaxValidation($model);

		

		

		

		//$this->performAjaxValidation1($acl);

		

		//$valid=$model->validate();

		//$valid=$acl->validate() && $valid;

		

		


		if(isset($_POST['user'], $_POST['acl']))

		{

			$model->attributes=$_POST['user'];

			$acl->attributes=$_POST['acl'];

			if($model->save() && $acl->save())

				$this->redirect(array('view','id'=>$model->id));

		}


		$this->render('create',array(

			'model'=>$model,

			'acl'=>$acl

		));

	}

Now the funny part is the ajax validation actually works, but only for one model at a time

If I call $this->performAjaxValidation1($acl); first this validation is done perfectly, but if I call $this->performAjaxValidation($model); first that is done successfully but the the second one is not performing as it should. If field is empty it turns green although it should turn red. Whichever ones of these I’m calling first that method will work 100%.

Validation methods look like this


protected function performAjaxValidation($model)

	{

		if(isset($_POST['ajax']) && $_POST['ajax']==='user-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}

	}

	

	/**

	 * Performs the AJAX validation.

	 * @param CModel the model to be validated

	 */

	protected function performAjaxValidation1($acl)

	{

		if(isset($_POST['ajax']) && $_POST['ajax']==='user-form')

		{

			echo CActiveForm::validate($acl);

			Yii::app()->end();

		}

	}

I’m desperate for a solution, please help

CActiveForm::validate() also can take an array as first parameter

http://www.yiiframework.com/doc/api/CActiveForm#validate-detail

I would give this a try:




protected function performAjaxValidation($model, $acl)

{

  if(isset($_POST['ajax']) && $_POST['ajax']==='user-form')

  {

    echo CActiveForm::validate(array($model, $acl));

    Yii::app()->end();

  }

}



(not tested)

/Tommy

And it was that easy :wink: Thanx I tested this and it workx like a charm!!!!!! Thanx Tommy, I appreciate it

is it possible to use this together?


$form->errorSummary($model,$modelVessel);

i got error on that


$form->errorSummary(array($model,$modelVessel));

Hi there,

Thanks for your fine explanation. I’ve tried this, though still remain with the same problem as YiiNewBy.

The slight difference is that I use multiple instances from an array. The idea is to offer a user the

possibility to insert multiple users in once (ticket order system). Therefore I create an array of new ‘ShortUser’ models before rendering the page, which I can than include when the number of users is set.

Thus, initially the page only shows the form of the ‘Bezoeker (=visitor)’ model, including a dropdown with

numerical values. When for example 2 is selected, the first two models of $extraUser are shown using:




for($i = 0; $i < $numSelected; $i++){

  $this->renderPartial('//bezoeker/_extra_user_form', array('model'=>$extraUsers[$i], 'form'=>$form, 'i'=>$i));

}

This is the current state. Since I first want to develop a need form before creating this properly using an ajax request on change of the Number field

===

Below the code I am using now.


public function actionRegistreer(){

  $maxAantal = 4;

  $model = new Bezoeker;

  $extraUsers = array();

  for($i = 0; $i < $maxAantal; $i++){

    $extraUsers[$i] = new ShortBezoeker('insert');

  }		 

		

  $allModels = array_merge(array($model), $extraUsers);

  $this->performAjaxValidation($allModels);

  ...



However, when using for my form:


'enableAjaxValidation' => true,

  'clientOptions'=>array(

  'validateOnChange'=>true,

  'validateOnSubmit'=>true,

),

this results in the case that:

On submit the correct rules are checked (for example an ‘email’ rule),

however, onChange the input fields are just ‘colored green’…

Is there something I am missing?

=====

By the way, for the multiple forms I use:


echo $form->textFieldRow($model,'['. $i .']email',array('class'=>'span5','maxlength'=>35));

This is the form rendered by the first line of code shown above (the renderPartial)

I hope someone can help me with this issue, since I am starting to get desperate…

Thanks in advance!

With kind regards,

Reinier

In addition, when enabling ‘enableClientValidation’, the validation works for the ShortBezoeker.

Unfortunatelly, then all models are validated, instead of only the ones visible.

Currently, I have selected the possibility to render all ShortBezoeker forms on the page and do

I only show the forms corresponding the number selected. On ClientValidation all rules are shown

in the sourcecode of the file and all forms (also the hidden ones) are validated.

Therefore, my problem remain the same…

Can someone help me with this issue?

you need to write it this way


$form->errorSummary(array($model,$modelVessel));