With Yii you can use one CActiveForm for collecting data for two or more models with ajax validation and client validation.
According this article you can also create a form with ajax validation for both models.
You have two models $a and $b.
create.php
<?php $form = $this->beginWidget('CActiveForm', array(
'id'=>'user-form',
'enableAjaxValidation'=>true,
)); ?>
<?php echo $form->errorSummary(array($a,$b)); ?>
<div class="row">
<?php echo $form->labelEx($a,'firstName'); ?>
<?php echo $form->textField($a,'firstName'); ?>
<?php echo $form->error($a,'firstName'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($b,'lastName'); ?>
<?php echo $form->textField($b,'lastName'); ?>
<?php echo $form->error($b,'lastName'); ?>
</div>
<?php $this->endWidget(); ?>
controller:
public function actionCreate()
{
$a=new User;
$b=new Info;
$this->performAjaxValidation(array($a,$b));
if(isset($_POST['User'],$_POST['Info']))
{
// populate input data to $a and $b
$a->attributes=$_POST['User'];
$b->attributes=$_POST['Info'];
// validate BOTH $a and $b
$valid=$a->validate();
$valid=$b->validate() && $valid;
if($valid)
{
// use false parameter to disable validation
$a->save(false);
$b->save(false);
$this->redirect('index');
}
}
$this->render('create',array('a'=>$a,'b'=>$b));
}
protected function performAjaxValidation($models)
{
if(isset($_POST['ajax']) && $_POST['ajax']==='user-form')
{
echo CActiveForm::validate($models);
Yii::app()->end();
}
}
Thats all, now you have form with 2 models and ajaxValidation.
error summary
I think this:
echo $form->errorSummary($model);
should be changed to something like:
echo $form->errorSummary($a); echo $form->errorSummary($b);
or the validation will not work...
great article , learn some new skills!
i never known that isset() function can accepts more than one parameters util seen this article :D; and found that : CActiveForm::validate($models); the validate function can give many models ; well done!
comment
@rusalex, you should probably use a transaction, otherwise if one model->save() fails, you might have some dangling models
@redguy, did you test it? errorSummary can accept an array of models
also note that isset() does and AND, not an OR
@el chief
@el chief: now is also ok. Earlier there was reference to not declared variable: $model.
@el chief
yes, it's a simple ideal way to save data. you need to write your own validation process.
saving not good
if($a->save() && $b->save())
is not good because if for any reason ajax validation pass and then the validation at $b-save() fails the $a record will be saved.
Take a look at the original article for validating / saving the data.
Fixed
@mdomba, fixed.
FK has a temporary value.
I modified that FK has a temp value in order to pass validity check.
It will rollback as deleting a record of the referenced table if fails to save a record of the referencing table.
It seems to work fine.
$user=new User('register'); $profile=new UserProfile('create'); if(isset($_POST['User'])&&isset($_POST['UserProfile'])) { $user->attributes=$_POST['User']; // FK user_id has a temporary value as zero to validate $profile->user_id=0; $profile->attributes=$_POST['UserProfile']; if($user->validate()&&$profile->validate()) { if($user->save()) { // FK now has a proper value. $profile->user_id=$user->id; if($profile->save()) $this->redirect(array('site/index')); else // rollback if fails to save profile $user->delete(); } } }
Gratitude
Thank you SO MUCH.
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.