muitosefala
muitosefala

Reputation: 13

yii2 - multiple rows load into same table from one form

I am trying to save a schedule of working days on a table multiple rows at once... I am doing this wrong, still giving me errors. I have seen tabular inputs from others, but can't get this right. I really need some other eyes on it.

I have a similar problem as https://phppedia.com/en/knowledge-base/32481399/yii2-insert-multiple-records-of-a-same-table

model:

public
    function rules()
    {
        return [
            ['store_id', 'string'],
            ['day', 'string'],
            ['start_hour', 'string'],
            ['end_hour', 'string'],
            ['holiday','boolean'],
        ];
    }

controler:

public function actionCreate()
    {
        $count = count(Yii::$app->request->post('Openhour', []));
        $model = [new Openhours()];
        for ($i = 1; $i < $count; $i++) {
            $model[] = new Openhours();
        }

        if ($model->loadMultiple($model, Yii::$app->request->post())) {
            foreach ($model as $model) {
               $model->save(false);
            }
        }

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

_form

<?php $stores = Stores::getAll() ?>
<?php foreach ($stores as $store): ?>
    <?php if ($store->id !== 0): ?>
        <?php $listData[$store->id] = [$store->id => $store->title]; ?>
    <?php endif; ?>
<?php endforeach; ?>




<?php $form = ActiveForm::begin(['enableAjaxValidation' => true, 'options' => ['class' => 'model-form'],]); ?>
<?php foreach ($model as $index => $model): ?>


    <div class="row row-cols-3">
        <div class="col">
            <h5>
                <?php if ($store->title === Yii::$app->user->identity->username) : ?>
                    <?= $form->field($model, '[$index]store_id')->hiddenInput(['value' => $store->title])->label($store->title) ?>
                <?php else: ?>
                    <?= $form->field($model, '[$index]store_id')->dropDownList($listData, ['prompt' => 'Select...']); ?>
                <?php endif; ?>
            </h5>
        </div>
        <div class="col">Opening</div>
        <div class="col">Close</div>
    </div>


    <?php $days = Storedays::getAll() ?>
    <?php foreach ($days as $day): ?>

        <div class="row row-cols-3">
            <div class="col">
                <div class="row justify-content-between">
                    <div class="col">
                        <h6><?= $day->name ?></h6>
                        <?= $form->field($model, '[$index]day')->hiddenInput(['value' => $day->name, 'id' => 'day' . $day->id])->label(false) ?>
                    </div>
                    <div class="col">
                        <?= $form->field($model, '[$index]holiday')->checkbox(['selected' => $model->holiday, 'id' => 'holiday' . $day->id])->label(false) ?>
                    </div>
                </div>
            </div>
            <div class="col">
                <?= $form->field($model, '[$index]start_hour')->Input('text')->widget(TimePicker::class, ['options' => ['id' => 'start_hour' . $day->id], 'pluginOptions' => ['maxHours' => '8', 'template' => 'dropdown', 'showSeconds' => false, 'showMeridian' => false, 'minuteStep' => 15,]])->label(false) ?>
            </div>
            <div class="col">
                <?= $form->field($model, '[$index]end_hour')->Input('text')->widget(TimePicker::class, ['options' => ['id' => 'end_hour' . $day->id], 'pluginOptions' => ['maxHours' => '8', 'template' => 'dropdown', 'showSeconds' => false, 'showMeridian' => false, 'minuteStep' => 15,]])->label(false) ?>
            </div>
        </div>

    <?php endforeach; ?>

    <?php if (IS_ROOT) : ?><?= $form->field($model, '[$index]slug') ?><?php endif; ?>

    <?= Html::submitButton('save', ['class' => 'btn btn-primary']) ?>

    <hr class="mb-3">

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

Upvotes: 1

Views: 1155

Answers (1)

ustmaestro
ustmaestro

Reputation: 1283

First you have an array of objects and you must use plural name instead.

So model become models.

Second you must use functions for loading multiple models from request Model::loadMultiple($models) and for validate multiple models Model::validateMultiple($models).

Now in your controller:

public function actionCreate()
{
    $count = count(Yii::$app->request->post('Openhour', []));
    $models = [new Openhours()];
    for ($i = 1; $i < $count; $i++) {
        $models[] = new Openhours();
    }

    if (Model::loadMultiple($models, Yii::$app->request->post()) && Model::validateMultiple($models)) {
        foreach ($models as $model) {
            $model->save(false);
        }
    }

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

Now in your _form.php change the line:

<?php foreach ($model as $index => $model): ?>

To:

<?php foreach ($models as $index => $model): ?>

Upvotes: 1

Related Questions