Menus

Thursday, 27 October 2016

Yii Tabular Input


Yii2 Insert multiple records of a same table




Collecting Tabular Input

           Sometimes we want to collect user input in a batch mode. That is, the user can enter the information for multiple model instances and submit them all at once. We call this tabular input because the input fields are often presented in an HTML table.
          To work with tabular input, we first need to create or populate an array of model instances, depending on whether we are inserting or updating the data. We then retrieve the user input data from the $_POST variable and assign it to each model. A slight difference from single model input is that we retrieve the input data using $_POST['ModelClass'][$i] instead of$_POST['ModelClass'].

In contrast to the single model forms explained before, we are working with an array of models now. This array is passed to the view to display the input fields for each model in a table like style and we will use helper methods of yii\base\Model that allow loading and validating multiple models at once:

This example for validate and save tabular data. Help to avoid insert many times the same table with ActiveForm.



Modify your controller code to use multiple models


<?php

namespace backend\modules\tools\controllers;

use Yii;
use backend\modules\tools\models\Products;
use backend\modules\tools\models\ProductsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\base\Model;

/**
 * ProductsController implements the CRUD actions for Products model.
 */
class ProductsController extends Controller
{

.................
................

public function actionCreate()
    {

        //Find out how many products have been submitted by the form
        //$count = count(Yii::$app->request->post('Product', []));
        $count=4;

        //Send at least one model to the form
        $prts = [new Products()];

        //Create an array of the products submitted
        for($i = 1; $i < $count; $i++) {
            $prts[] = new Products();
        }
        
        
        //Load and validate the multiple models
        if (Model::loadMultiple($prts, Yii::$app->request->post()) && Model::validateMultiple($prts)) {

            foreach ($prts as $product) {

                //Try to save the models. Validation is not needed as it's already been done.
                $product->save(false);

            }
            return $this->redirect('view');
        }

        return $this->render('create', ['prts' => $prts]);
                
    }

..........
...........
}


 The view file for the form needs to be altered like this, to use the multiple models;


<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;

/* @var $this yii\web\View */
/* @var $model backend\modules\tools\models\Products */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="products-form">

    <?php $form = ActiveForm::begin(); ?>
 
   <table>
        <tr>
            <td>Product Name</td>
            <td>Product Qty</td>
            <td>Product Price</td>
        </tr>
        <?php foreach ($prts as $index => $product) { ?>       
        <tr>            
            <td><?= $form->field($product, "[$index]product_name")->textInput(['maxlength' => true])->label(FALSE) ?></td>
            <td><?= $form->field($product, "[$index]product_quantity")->textInput()->label(FALSE) ?></td>
            <td><?= $form->field($product, "[$index]product_price")->textInput(['maxlength' => true])->label(FALSE) ?></td>        
        </tr> 
       <?php } ?>
    </table>
     
    <div class="form-group">
        <?= Html::submitButton($product->isNewRecord ? 'Create' : 'Update', ['class' => $product->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
    </div>

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

</div>


View shows




Solutions:
I want to add multiple records from a form into a table.