Multi Model Form - How To Deal With Validation Rules ?

We have a Team Form, each team can have several members. (at least 1, until 5);

Both, team and each member, should be validated, client and server side.

The user, may choose, live, to add or remove members fields (until 5).

Team is a model.

Member is another model.

For example:

If the user adds two new members to be filled in, then, those two fieldsets should be validated.

If they are hidden, the validation should not be triggered.

We should be able to benefit from "Yii Validation scenarios".

While this may seem simple, it doesn’t seem to be possible using Yii structure, even extending it, until now, and as far as we were able to see, nothing as been accomplish.

Does anyone was able to accomplish this, or other similar scenario, using rules method on the models (to benefit from validation handled by Yii) ?

This is a very common request from clients and, it would be nice if Yii 2.0 could properly deal with such scenarios.

Please advice

I dont know if this what you looking for here some links might help you

http://www.yiiframework.com/wiki/218/how-to-use-single-form-to-collect-data-for-two-or-more-models-cactiveform-and-ajax-validation-edition/

http://www.yiiframework.com/wiki/19/how-to-use-a-single-form-to-collect-data-for-two-or-more-models/

http://www.yiiframework.com/wiki/291/update-two-models-with-one-view/

I was just checking those ATM.

I’m still not sure, if that will deal with the fact that, IF the fieldsets aren’t visible, THEN, we should skipped validation on those fields. Do you happen to know, if scenarios may be used for those circumstances ?

Thanks again.

I can add this couple of resources:

http://www.yiiframew…form-inc-image/

http://www.larryullm…s-in-yii-forms/

Hello again,

First of all, thanks for those documentations. Actually, I believe none of those, truly describes this scenario, since this not just a question of having two models, because that relation is ok. The issue, however, may rely on the fact that one of those models (Members) is "child" of another "Team".

I can only save Members, if I SAVE Team (to retrieve the Team ID and pass it to Members Team ID).

Then we should iterate over all Members, and,validate each of them.

I have accomplish that. No problem.

The issue relies on the validation.

I got a very bizarre behaviour:

If, on CActiveForm widget, we:

  • set Ajax Validation to TRUE;

  • set Client Side Validation to FALSE;

Only the Team model displays the messages. Why? No idea.

If, on CActiveForm Widget, we:

  • set Ajax Validation to TRUE;

  • set Client Side Validation to TRUE;

We DO get all validation messages displayed, both on Team and Member form fields.

I know that the Members are also being validated via Ajax, because, I can see the message that

I setup on the MODEL Rules method. Why like this it works for both? No idea.

Now, the problem is:

On the form, the Members could be either 1, 2 or 3.

We wish to allow the validation ONLY on those fields that are visible.

If they aren’t visible, we shouldn’t validate that.

I’ve tried to create a beforeValidate script, to disable=disable the input fields, but the client side validation seems to NOT care about if they are disabled or not, I get messages there as well.

This is kind of hard to explain, I promise to place all my code here, for others to use once this is done, but, I would like to request if someone, could be kind enough to dispense some minutes on a chat session in order to check the issue I’m referring here.

Or, I can place, my PerformAjax validation script, my controller script, my _form partial. (but it’s really a lot of code, and I really believe a chat would be more effective).

If you believe you could help here, please PM.

IF we end up seeing that this actually, gives some work to be done properly, I don’t mind to pay from my pocket if I have to.

Instead of toggle’ing the visibility, couldn’t you remove the fields from the DOM?

There are many ways to approach that problem, here is a very simple approach add a field in your products table call it items_in_stock when a person adds a product in his cart you can deduct one out of total number this will take care off the larger problem even if you have more than one products.

@All

I still don’t understand why I can’t see any validation messages on Members here:

Team Controller:


public function actionMember($index){

            $model = new TeamMember();

            if (Yii::app()->request->isAjaxRequest)

            {

                $this->renderPartial('_member',array(

                    'model'=> $model, 'index'=> $index

                ));  

            }  

        } 

Member Model:


return array(

            array('team_id, name, birthdate, email, phone', 'required'),

_member:


<div class="row-member<?php echo $index; ?>">

    <h3>Member <?php if ($index+1==1){echo $index+1 . '(captain)';} else echo $index+1; ?></h3>

    <?php echo CHtml::activeLabel($model, "[$index]name",array('class'=>'member')); ?>

    <?php echo CHtml::activeTextField($model, "[$index]name",array('class'=>'member')); ?>


    </div> ...

_form:


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

    'id'=>'team-form',

        'enableAjaxValidation'=>false,

        'enableClientValidation'=>true,

        'clientOptions'=>array(

            'validateOnSubmit'=>true,


        ),

        'htmlOptions' => array('enctype' => 'multipart/form-data'),

)); ?>

    <fieldset>

            <section id="members"></section>

            <?php echo CHtml::button('Add Member', array('class'=>'addMember'));?>

        </fieldset>


<script>

$('.addMember').click(function(){


        $.ajax({

            success: function(html){

                $('#members').append(html);

                },

            type: 'get',

            url: '<?php echo $this->createUrl('member'); ?>',

            data: {index:$('#members div').size()},

            cache: false,

            dataType: 'html'

</script>

processOutput was set to true and false, and false, true and… render() was called instead of renderPartial(), and those were just desperate moves. :s

Can I have any clue, or tip on why can’t we get any validation messages on the partial views here ?

pls follow the yii-user http://www.yiiframework.com/extension/yii-user/ module style . dont get confused its very easy.

pls download it and check for profile and profile_field

http://www.yiiframework.com/extension/yii-user/

@Rajith R,

Thanks for trying to help.

I’ve download it, and I’ve tried to study it.

As far as I was able to check there, it will be a question of:

Extending CActiveForm;

Then Extend Chtml;

Then, having some array having thinks like:




if ($field->required==ProfileField::REQUIRED_YES_NOT_SHOW_REG||$field->required==ProfileField::REQUIRED_YES_SHOW_REG)

					array_push($required,$field->varname);

				if ($field->field_type=='FLOAT')

					array_push($float,$field->varname);

				if ($field->field_type=='DECIMAL')

					array_push($decimal,$field->varname);

				if ($field->field_type=='INTEGER')

					array_push($numerical,$field->varname);

				if ($field->field_type=='VARCHAR'||$field->field_type=='TEXT') {

					$field_rule = array($field->varname, 'length', 'max'=>$field->field_size, 'min' => $field->field_size_min);

					if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);

					array_push($rules,$field_rule);

				}

And also, as well, having some [b]getFields/b


public function getFields() {

		if ($this->regMode) {

			if (!$this->_modelReg)

				$this->_modelReg=ProfileField::model()->forRegistration()->findAll();

			return $this->_modelReg;

		} else {

			if (!$this->_model)

				$this->_model=ProfileField::model()->forOwner()->findAll();

			return $this->_model;

		}

	}

I’m really not at the same level for sure, as you are regarding Yii.

And clearly easy for you, is not the same as easy for me.

:(

For me this is the same as telling:

“Do your own solution and good luck”. :(

hi…hi… :)