Yii2: Nested Dynamic Form wbraganca added more fields
Yii2: Nested Dynamic Form wbraganca added more fields
I am using wbragnaca dynamic form for yii2, add & remove button working properly on create, flawless. But when I update on the Instrument the nested form which is the Item is that when I click on the add button it adds 3 fields instead of just one.
Here is the form before I click on the Items - Statement button:
Instrument Form before
Here is after I click the add button on the Item:
Instrument Form after
Here is my database design:
DATABASE
Here is my code,
_form.php
<?php
use yiihelpersHtml;
use yiiwidgetsActiveForm;
use wbragancadynamicformDynamicFormWidget;
/* @var $this yiiwebView */
/* @var $model appmodelsInstrument */
/* @var $form yiiwidgetsActiveForm */
?>
<?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>
<div>
<?= $form->field($modelInstrument, 'name')->textInput(['maxlength' => true,'style'=>'width: 50%', 'placeholder'=>'Name'])->label(false) ?>
<?= $form->field($modelInstrument, 'description')->textArea(['rows' => '6', 'placeholder'=>'Description'])->label(false) ?>
</div>
<div class="padding-v-md">
<div class="line line-dashed"></div>
</div>
<br/>
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper',
'widgetBody' => '.container-items',
'widgetItem' => '.section-item',
'min' => 1,
'insertButton' => '.add-section',
'deleteButton' => '.remove-section',
'model' => $modelsSection[0],
'formId' => 'dynamic-form',
'formFields' => [
'name',
'description',
],
]); ?>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th >Sections</th>
<th style="width: 650px; height: 30px;">Items</th>
<th class="text-center" style="width: 30px; height: 30px;">
<button type="button" class="add-section btn btn-success btn-xs"><span class="glyphicon glyphicon-plus" style="font-size: 10px"></span></button>
</th>
</tr>
</thead>
<tbody class="container-items">
<?php foreach ($modelsSection as $indexSection => $modelSection): ?>
<tr class="section-item">
<td class="vcenter">
<?php
// necessary for update action.
if (! $modelSection->isNewRecord)
echo Html::activeHiddenInput($modelSection, "[$indexSection]id");
?>
<?= $form->field($modelSection, "[$indexSection]name")->label(false)->textInput(['placeholder'=>"Name"]) ?>
<?= $form->field($modelSection, "[$indexSection]description")->label(false)->textArea(['rows' => '6', 'placeholder'=>'Description']) ?>
</td>
<td>
<?= $this->render('_form-item', [
'form' => $form,
'indexSection' => $indexSection,
'modelsItem' => $modelsItem[$indexSection],
]) ?>
</td>
<td class="text-center vcenter" style="width: 40px; verti">
<button type="button" class="remove-section btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus" style="font-size: 10px"></span></button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php DynamicFormWidget::end(); ?>
<div class="form-group">
<?= Html::submitButton($modelInstrument->isNewRecord ? 'Create' : 'Update', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
_form-item.php
<?php
use yiihelpersHtml;
use wbragancadynamicformDynamicFormWidget;
?>
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_inner',
'widgetBody' => '.container-rooms',
'widgetItem' => '.room-item',
'min' => 1,
'insertButton' => '.add-item',
'deleteButton' => '.remove-item',
'model' => $modelsItem[0],
'formId' => 'dynamic-form',
'formFields' => [
'statement'
],
]); ?>
<table class="table table-bordered">
<thead>
<tr>
<th >Statements</th>
<th class="text-center">
<button type="button" class="add-item btn btn-success btn-xs"><span class="glyphicon glyphicon-plus" style="font-size: 10px"></span></button>
</th>
</tr>
</thead>
<tbody class="container-rooms">
<?php foreach ($modelsItem as $indexItem => $modelItem): ?>
<tr class="room-item">
<td class="vcenter">
<?php
// necessary for update action.
if (! $modelItem->isNewRecord)
echo Html::activeHiddenInput($modelItem, "[$indexSection][$indexItem]id");
?>
<?= $form->field($modelItem, "[$indexSection][$indexItem]statement")->label(false)->textInput(['maxlength' => true]) ?>
</td>
<td class="text-center vcenter" style="width: 40px;">
<button type="button" class="remove-item btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus" style="font-size: 10px"></span></button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php DynamicFormWidget::end(); ?>
InstrumentController.php actionUpdate
public function actionUpdate($id)
$modelInstrument = $this->findModel($id);
$modelsSection = $modelInstrument->sections;
$modelsItem = ;
$oldItems = ;
if (!empty($modelsSection))
foreach ($modelsSection as $indexSection => $modelSection)
$items = $modelSection->items;
$modelsItem[$indexSection] = $items;
$oldItems = ArrayHelper::merge(ArrayHelper::index($items, 'id'), $oldItems);
if ($modelInstrument->load(Yii::$app->request->post()))
// reset
$modelsItem = ;
$oldSectionIDs = ArrayHelper::map($modelsSection, 'id', 'id');
$modelsSection = Model::createMultiple(Section::classname(), $modelsSection);
Model::loadMultiple($modelsSection, Yii::$app->request->post());
$deletedSectionIDs = array_diff($oldSectionIDs, array_filter(ArrayHelper::map($modelsSection, 'id', 'id')));
// validate Instrument and Section models
$valid = $modelInstrument->validate();
$valid = Model::validateMultiple($modelsSection) && $valid;
$itemsIDs = ;
if (isset($_POST['Item'][0][0]))
foreach ($_POST['Item'] as $indexSection => $items)
$itemsIDs = ArrayHelper::merge($itemsIDs, array_filter(ArrayHelper::getColumn($items, 'id')));
foreach ($items as $indexItem => $item)
$data['Item'] = $item;
$modelItem = (isset($item['id']) && isset($oldItems[$item['id']])) ? $oldItems[$item['id']] : new Item;
$modelItem->load($data);
$modelsItem[$indexSection][$indexItem] = $modelItem;
$valid = $modelItem->validate();
$oldItemsIDs = ArrayHelper::getColumn($oldItems, 'id');
$deletedItemsIDs = array_diff($oldItemsIDs, $itemsIDs);
if ($valid)
$transaction = Yii::$app->db->beginTransaction();
try
if ($flag = $modelInstrument->save(false))
if (! empty($deletedItemsIDs))
Item::deleteAll(['id' => $deletedItemsIDs]);
if (! empty($deletedSectionIDs))
Section::deleteAll(['id' => $deletedSectionIDs]);
foreach ($modelsSection as $indexSection => $modelSection)
if ($flag === false)
break;
$modelSection->instrument_id = $modelInstrument->id;
if (!($flag = $modelSection->save(false)))
break;
if (isset($modelsItem[$indexSection]) && is_array($modelsItem[$indexSection]))
foreach ($modelsItem[$indexSection] as $indexItem => $modelItem)
$modelItem->section_id = $modelSection->id;
if (!($flag = $modelItem->save(false)))
break;
if ($flag)
$transaction->commit();
return $this->redirect(['view', 'id' => $modelInstrument->id]);
else
$transaction->rollBack();
catch (Exception $e)
$transaction->rollBack();
return $this->render('update', [
'modelInstrument' => $modelInstrument,
'modelsSection' => (empty($modelsSection)) ? [new Section] : $modelsSection,
'modelsItem' => (empty($modelsItem)) ? [[new Item]] : $modelsItem
]);
I copy the code from wbraganca's website. I change the code according to my need. But the update, just like I said when I want to update and add more Items on my Section the field adds 3 fields than just one.
I read the documentation and still I cant find the error.
Here is the Video to what happen when I click on the add button
foreach
Please read Under what circumstances may I add “urgent” or other similar phrases to my question, in order to obtain faster answers? - the summary is that this is not an ideal way to address volunteers, and is probably counterproductive to obtaining answers. Please refrain from adding this to your questions.
– halfer
Sep 16 '18 at 21:01
I am sorry for that. halfer. Muhammad I already read the documentation and understand it but I just dont know what is the error here.
– ResUta
Sep 17 '18 at 8:42
I copy-pasted your code with the exact db structure. The view seems just fine. See screenshot. [ ibb.co/iO5pbe ] Are you sure you've added the model relations correctly? Try to use github.com/mootensai/yii2-relation-trait. It will make dynamic forms easier.
– Imtiaz
Sep 17 '18 at 20:55
The bug only appears when I update the Instrument. Creating it works flawless. So Im wondering why, Update uses same file as create so why is this happening.
– ResUta
Sep 18 '18 at 10:30
0
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy
you should read the documentation before starting the code, that's how you integrate and transform the code according to your requirements, that is your homework and you should do that , read through the docs carefully , how it creates the nested form and what is the role of
foreach
loop for creating the fields– Muhammad Omer Aslam
Sep 16 '18 at 14:48