1

I'm trying to merge 3 models to create a fourth one. I have model1, model2 and model3 and I want to merge them into modelMaster. I've also created controllers for all of them. When I call modelMaster/create action, I render the modelMaster/create view which renders the modelMaster/_form view. Inside this _form view, I also want to render model1/_form, model2/_form and a CHtml::dropDownList(), wich takes datas from model3. However, this doesn't work. How can I combine these three different views into one another?

tereško
  • 58,060
  • 25
  • 98
  • 150
acidghost
  • 484
  • 4
  • 14
  • 1
    What happens when you do this? You said it doesn't work, but what happens? Does the script crash, is no output produced, etc.? – Ricardo Altamirano Jun 26 '12 at 16:37
  • it nests `form` elements! so also if I click on the main submit button it does nothing! – acidghost Jun 26 '12 at 17:07
  • well you have to show the code you have now, in your form. and also tell what exact behavior you want, i.e how do you want the forms to behave, if you don't want nesting. please be a little more clear on your question. – bool.dev Jun 27 '12 at 03:04

3 Answers3

1

If you try to skip the form generate from the _form views and use unique model names, I think you can use this manual: single form with more models So the generate of the form definition handles always the parent view and the _form's only the inputs

The other way to use single model in views, create a form model by extend CFormModel, and handle the data binding between this model and the wrapped submodels

PazsitZ
  • 131
  • 2
1

If you want to nest several forms into one master form you have to adjust the form templates accordingly. All of your modelMaster/create, model1/_form, model2/_form-views create and render a new CActiveForm (and thus several <form> tags).

Since you cannot nest form-elements in html (how should html know which action to pass the data to) you have to avoid this by doing the following:

  1. Extract the inputs of the form you want to nest into a new view, e.g. model1/_formInputs would look like

    ...
    <?php echo $form->labelEx($model,'name'); ?>
    <?php echo $form->textField($model,'name');
    <?php echo $form->error($model,'name');
    ...
    
  2. alter the model1/create and the other views and get a reference to the form created there, by assigning the return of $this->beginWidget to the variable $form (if not already done):

    <?php $form = $this->beginWidget('CActiveForm', array(
        'id'=>'foo',
    )); ?>
    

    replace the former input fields with

    <?php $this->renderPartial('model1/_formInputs', array('form' => $form); ?>
    

    Now, for example the old model1/create-view should work as expected

  3. To get your multi-model-form working you just have to get the reference to the form created in modelMaster/create and use it to renderPartial all */_formInputs you require. Please also remember to include the models for the inputs into the renderPartial-call. So modelMaster/create would look something like:

    <?php $form = $this->beginWidget('CActiveForm', array(
        'id'=>'foo',
    )); ?>
    
    /* Master Inputs here */
    
    // Rendering other models' inputs
    <?php $this->renderPartial('model1/_formInputs', array('form' => $form, 'model' => $model1); ?>
    <?php $this->renderPartial('model2/_formInputs', array('form' => $form, 'model' => $model2); ?>
    
    /* Render Form Buttons here */
    
    <?php $this->endWidget(); ?>
    
burnedikt
  • 962
  • 5
  • 17
0

Submit with Ajax, in Yii it is easy to do and it will keep things easy to understand in the controllers, each controller will have a save and respond with json to confirm the save. There is already ajax validation.

    /**
 * Performs the AJAX validation.
 * @param CModel the model to be validated
 */
protected function performAjaxValidation($model)
{
    if(isset($_POST['ajax']) && $_POST['ajax']==='employee-form')
    {
        $valid = CActiveForm::validate($model);
        if(strlen($valid) > 2) {
            echo $valid;
            Yii::app()->end();
        }       
    }
}   

As you can see I have modified it to return the error if there is one (validate returns [] if it is valid, I should probably check for that instead of strlen >2 ), otherwise let the script continue, in this case it will go to the save function.

Mihai P.
  • 9,307
  • 3
  • 38
  • 49