Two forms on the same page and scenario validation

Basically I have two forms on my page and the validation should only apply to the form that is submitted. I have created scenarios for both these forms and set them in my controller:

$model->setScenario(‘Send’);

$model->setScenario(‘Close’);

Firstly this does not render the form labels correctly, i.e. asterisks on the required fields. The second scenario overrides the first one. And upon submitting the ‘send’ form for example, the ‘close’ form gets validated instead.

Anybody got any suggestions? The two forms are in the same model (Enquiry) and in controller action ‘actionView’. Am I doing this incorrectly?

I actually managed to figure this out:




$model=$this->loadModel();

$enquiry=Enquiry::model()->findByPk($_GET['id']);


$model->setScenario('Send');

$enquiry->setScenario('Close');


if($model->validate())

{

	...

}

if($enquiry->validate())

{

	...

}






if ($_POST['Model']){

     // code for validate and save First model

}

if ($_POST['Enquiry']){

     // code for manage and validate Enquiry model

}



As I know if there is two forms on page, when you submit first form, then in POST should be only first form.

Correct me if I’m wrong.

@GSTAR:

I’m in a similar situation as you were, I have two forms on one page, and wish to send both forms’ data at once.

as @diggy says, the POST contains only the first form. How did you manage to send two forms at once?

Yes but I’m using SCENARIOS. The problem was not with capturing the post data, but instead applying the correct scenario upon form load. I figured it out anyway, as above.

OK, scenarios or not, how would you submit two forms at once? I only get the first form’s data in the POST.

Why would you post two forms at the same time? Do you mean two models? If that is so, there a couple of ways of doing it, some resources to look at

http://www.yiiframework.com/doc/cookbook/19/

http://www.yiiframework.com/forum/index.php?/topic/9476-

I had a similar situation (2 forms for the same model one 1 page but in different scenarios). I wanted to use 2 independent model objects for this. The problem is that both use the same name in $_POST ($_POST[‘Contact’] in my case as they both are objects of class ‘Contact’). I solved it by “misusing” the tabular input mechanism:

View:




<?php echo CHtml::fom(); ?>

<div class="row">

  <?php echo CHtml::label($modelA,'[form1]name'); ?>

  <?php echo CHtml::textField($modelA'[form1]name' ?>

</div>

...

<?php echo CHtml::endForm(); ?>




<?php echo CHtml::fom(); ?>

<div class="row">

  <?php echo CHtml::label($modelB,'[form2]name'); ?>

  <?php echo CHtml::textField($modelB'[form2]name' ?>

</div>

...

<?php echo CHtml::endForm(); ?>

Action:




public function actionContact()

{

    $modelA= new Contact('scenarioA');

    $modelB= new Contact('scenarioB');

    

    if (isset($_POST['Contact']['form1'])) {

   	$modelA->attributres=$_POST['Contact']['form1'];

        // validate & process form1 here

    }


    if (isset($_POST['Contact']['form2'])) {

   	$modelB->attributres=$_POST['Contact']['form2'];

        // validate & process form2 here

    }

    $this->render('contact',array('modelA'=>$modelA, 'modelB'=>$modelB));

}

You must include both form inputs inside one <form> (CHtml::form() , CHtml::endForm()).

Missusing? For me, it is a great way of proven creativity with a mix of Yii’s nature knowledge. Good one…

Thanks, Antonio. I used the term “misuse” to emphasise, that tabular input usually uses numerical indices. Yii does not enforce numerical values here - for now. But this could change in the future (i hope it doesn’t ;) ). Developers should be aware of this risk.

Antonio Ramirez and Mike, thank you! You just made my day :) Those posts were exactly what I was looking for, posting two models from a single form.

I’m new to Yii, just been a week since I started using it, so my questions might be a little noobish :(

I hacked my way around this problem by appending the data of the second form to the first form using jQuery, but I’d love a clean solution, and now I have it :) Thanks again!

Why not to use 2 different actions with the same views?

That allow you not to misuse tabular input (because each form will submit to different actions), you can save lot of if and strange workaround. The two actions will share the same views, it looks very tasty solution:




public function actionContact1()

{

    $modelA= new Contact('scenarioA');

    $modelB= new Contact('scenarioB');

    

    if (isset($_POST['Contact'])) {

        $modelA->attributres=$_POST['Contact']['form1'];

        // validate & process form1 here

    }


    $this->render('contact',array('modelA'=>$modelA, 'modelB'=>$modelB));

}


public function actionContact2()

{

    $modelA= new Contact('scenarioA');

    $modelB= new Contact('scenarioB');




    if (isset($_POST['Contact'])) {

        $modelB->attributres=$_POST['Contact'];

        // validate & process form2 here

    }

    $this->render('contact',array('modelA'=>$modelA, 'modelB'=>$modelB));

}



This will repeat the code of validation and process the form, but if you are doing such a job I guess that this code is quite different, isn’t it?

Elloooww, Mike i try ur code, but i change the textField with fileField, i see the code is make senses but $attachment->attributes=$_POST[‘Attachment’][‘form1’] seems doesnt work coz this code :$attachment->save();

result an empty byte in my BLOB database

any idea?

thanks

If you didn’t already: Maybe first try to get it working with a single form, not using the above technique. You probably first need to find out why your file is not handled correctly. I think, zaccaria is an expert on files in BLOBS so maybe he has some idea …? ;)

thanks for ur reply mike,

i ended up by using my own way, which is not so gud i guess :P, but it works fine,

:)