Ajax Validation for tabular or dynamic input

Hi everyone,

After taking much time for searching, I have a solution to ajax validation for tabular or dynamic input. It works for me. Hopefully it is helpful for someone. It is not a perfect but it gives you the concept how to implement this.

First,remember to enable ajaxValidation in the CActiveForm.

Next, Gennerate the inputs in the view, for example:

[VIEW]




<div class="row">

<?php for($i=1;$i<=5;$i++) { 

	$m = new AgentPostcode('reg'); //your model

?>

			<?php echo $form->textField($m,"[$i]postcode"); ?>

			<?php echo $form->error($m,"[$i]postcode"); ?>

<?php } ?>

</div>



In the contoller, rewrite the validate function which is copied and a bit modified from CActiveForm





	public static function validate($models, $dynamicModel, $attributes=null, $loadInput=true)

	{

		//copy from CActiveForm:validate

		$result=array();

		if(!is_array($models))

			$models=array($models);

			

		foreach($models as $model)

		{

			if($loadInput && isset($_POST[get_class($model)]))

				$model->attributes=$_POST[get_class($model)];

			$model->validate($attributes);

			foreach($model->getErrors() as $attribute=>$errors)

				$result[CHtml::activeId($model,$attribute)]=$errors;

		}

		//end copying


		//your own customization

		for($count=1;$count<=5;$count++)

		{

			$dynamicModel->clearErrors();

			

			if($loadInput && isset($_POST[get_class($dynamicModel)][$count]))

				$dynamicModel->attributes=$_POST[get_class($dynamicModel)][$count];

			$dynamicModel->validate($attributes);

			

			foreach($dynamicModel->getErrors() as $attribute=>$errors)

				$result[get_class($dynamicModel) . '_' . $count . '_' . $attribute]=$errors;

		} 


		return function_exists('json_encode') ? json_encode($result) : CJSON::encode($result);

	}



Finally, in the controller, modify ajax perform function:




	    // For Ajax Validation

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

	    {

	    	$dynamicModel = new AgentPostcode('reg'); //your model

	        $validate = self::validate(array($model,$modelAC),$dynamicModel);

	        //$validate = CActiveForm::validate(array($model,$modelAC)); //original

 	        echo $validate;

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

	    }



That is all how to enable ajax validation for tabular or dynamic input.

Hope help someone.

You could publish a wiki

http://www.yiiframework.com/wiki/

very helpful , great job! :D

I think this is very helpful to perform tabular input ajax validation, I want to use it, but have several questions:

[list=1][] in ajax perform function: what does $modelAC mean?[]how to deal with the scenario that the tabular inputs items are dynamically generated ( you don’t know the $count)[/list]

Appreciate for your helping

At first:

Please excuse if my English is not perfect.

Thank you very much for sharing this!

Helped a lot for understanding how to solve this issue.

But I have still a little Problem…

Your solution works perfect when you generate the tabular input like that:


<?php for($i=1;$i<=5;$i++) { 

        $m = new AgentPostcode('reg'); //your model

?>

                        <?php echo $form->textField($m,"[$i]postcode"); ?>

                        <?php echo $form->error($m,"[$i]postcode"); ?>

<?php } ?>

But when you dynamically add new rows to tabular input

for example with JRrelCopy or a own "add row" Jquery function there is a Problem i was not able to solve…

The submitted dynamic items will be validated,

I receive a JSON Object with all errors,

but the validation-errors for the dynamic added fields are not shown in errorSummary and the "on Field error" …

Is there any solution for this?

Or do I have to "force the user" to use a "fixed" number of rows?

And "hide" them via Jquery?

I hope you could understand what I mean. :)

Best Regards

Thanks for posting this!!! =)

Sorry if i don’t understand, but when i have need to validate many models, i look into some tutorials, and API refernce and found this http://www.yiiframework.com/doc/api/1.1/CActiveForm/#validateTabular-detail, it works great for me.

@Newb you are right, but check the date of this thread, it’s from July 2011 and the method validateTabular() has been added only later

Yes, just saw someone write here today and top up this topic. It’s mainly for him and those who may enter here after topic come to the top.

:D Since this is my first ever post i would like to say thanx to the endless amount of hours you guys have saved me by posting your solutions in this forum!!!!

:blink: I recently bumped in to a new problem, i need to use both CActiveForm::validate() and CActiveForm::validateTabular().

I tried several things to get it to work, and finaly ended up with this dirty solution… :huh:




protected function MyperformAjaxValidation($model, $Cupons)

{

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

	  {

	  	$tabort = array("{", "}");

		$tmp_model = str_replace($tabort, "", CActiveForm::validate($model));

	  	$tmp_cupons = str_replace($tabort, "", CActiveForm::validateTabular($Cupons));

	  	

	  	echo = "{".$tmp_model.", ".$tmp_cupons."}";

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

	  }

}



::) I would like to get some input how to do it the Yii way :wink:

[size=2]I would do this:[/size]




$model = CJSON::decode(CActiveForm::validate($model));

$cupons = CJSON::decode(CActiveForm::validate($Cupons));

echo CJSON::encode(CMap::mergeArray($model, $cupons));

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



Prevents you from having to hack json as a string.

beezee, good solution!

I tried and worked! (with "validateTabular" in the second model).