Multiple models in the same view

Often, we can find many models of same or different class in a single view. First of all, remember that Yii2 encapsulates all the views' form attributes in the same container, named the same as the model class name. Therefore, when the controller receives the data, these will all be organized in a key of the $_POST array named the same as the model class name.

If the model class name is Customer, every form input name attribute will be Customer[attributeA_of_model] This is built with: $form->field($model, 'attributeA_of_model')->textInput().

In the case of multiple models of the same class, the container will again be named as the model class name but every attribute of each model will be inserted in an array, such as:

Customer[0][attributeA_of_model_0]
Customer[0][attributeB_of_model_0]
…
…
…
Customer[n][attributeA_of_model_n]
Customer[n][attributeB_of_model_n]

These are built with:

$form->field($model, '[0]attributeA_of_model')->textInput();
$form->field($model, '[0]attributeB_of_model')->textInput();
…
…
…
$form->field($model, '[n]attributeA_of_model')->textInput();
$form->field($model, '[n]attributeB_of_model')->textInput();

Note

Notice that the array key information is inserted in the attribute name!

So, when data is passed to the controller, $_POST['Customer'] will be an array composed by the Customer models and every key of this array, for example, $_POST['Customer'][0] is a model of the Customer class.

Example – saving multiple customers at the same time

Now let's see how to save three customers at once. We will create three containers, one for each model class that will contain some fields of the Customer model.

Create a view in basic/views/customers/createMultipleModels.php that contains a block of input fields repeated for every model passed from the controller:

<?php

use yiihelpersHtml;
use yiiwidgetsActiveForm;

/* @var $this yiiwebView */
/* @var $model appmodelsRoom */
/* @var $form yiiwidgetsActiveForm */
?>

<div class="room-form">

    <?php $form = ActiveForm::begin(); ?>

    <div class="model">
      
      <?php for($k=0;$k<sizeof($models);$k++) { ?>
          <?php $model = $models[$k]; ?>
          <hr />
          <label>Model #<?php echo $k+1 ?></label>
          <?= $form->field($model, "[$k]name")->textInput() ?>
          <?= $form->field($model, "[$k]surname")->textInput() ?>
          <?= $form->field($model, "[$k]phone_number")->textInput() ?>
      <?php } ?>
        
    </div>

<hr />

    <div class="form-group">
      <?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>

For each model all the fields will have the same validator rules of the Customer class, and every single model object will be validated separately.

Next create a new action in the customers controller in basic/controllers/CustomersController.php, named actionCreateMultipleModels. If the $_POST['Customer'] content is set, and if they are all validated and finally redirected to the grid action, it will save them all together; otherwise it will create three models of the Customer class:

    public function actionCreateMultipleModels()
    {
        $models = [];
        
        if(isset($_POST['Customer']))
        {
             $validateOK = true;
            
            foreach($_POST['Customer'] as $postObj)
            {
                $model = new Customer();
                $model->attributes = $postObj;
                $models[] = $model;

                $validateOK = ($validateOK && ($model->validate()));               
            }
            
            // All models are validated and will be saved
            if($validateOK)
            {
                foreach($models as $model)
                {
                    $model->save();
                }
                
                // Redirect to grid after save
                return $this->redirect(['grid']);
            }
        }
        else
        {
            for($k=0;$k<3;$k++)
            {
                $models[] = new Customer();
            }    
        }
        
        return $this->render('createMultipleModels', ['models' => $models]);
    }

It can be useful to create models in the controller because a large number of them and other validation checks are configured here.

Browse to http://hostname/basic/web/customers/create-multiple-models to see the complete page:

Example – saving multiple customers at the same time

Multiple models in the same view

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.103.210