Yii2: Nested Dynamic Form wbraganca added more fields - php

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 yii\helpers\Html;
use yii\widgets\ActiveForm;
use wbraganca\dynamicform\DynamicFormWidget;
/* #var $this yii\web\View */
/* #var $model app\models\Instrument */
/* #var $form yii\widgets\ActiveForm */
?>
<?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 yii\helpers\Html;
use wbraganca\dynamicform\DynamicFormWidget;
?>
<?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

Related

Getting a table column data as array with POST request in CakePHP

I have a form that has a table inside it and that table has a quantity column, I want to get the quantity of all products and put them in a quantity array in the controller, is there a way I can do that? For now, it doesn't work when I click Update Cart button. Here is my current code:
index page
<section class="section service border-top">
<div>
<?= $this->Form->create(null) ?>
<fieldset>
<?php if(isset($_SESSION['cart']) && !empty($_SESSION['cart'])){?>
<table id="cart-table" class="table table-bordered table-striped">
<thead>
<tr>
<th><?= 'Products' ?></th>
<th><?= 'Price'?></th>
<th><?= 'Quantity'?></th>
<th><?= 'Sub Total'?></th>
</tr>
</thead>
<tbody>
<?php foreach ($cart_items as $cart_item): ?>
<tr>
<td><?= $cart_item->name;?></td>
<td><span id="price"><?= "$ AU".$cart_item->price;?></span></td>
<td contenteditable='true'><?php echo $this->Form->number('quantity[]',['min'=>1, 'value'=>$cart_item->quantity]); ?></td>
<td><span id="total"><?php echo "$ AU".$cart_item->price * $cart_item->quantity?></span></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php }else{ ?>
You don't have any items in your cart. Add more?
<?php } ?>
</fieldset>
<?= $this->Form->button(__('Make a Payment'), ['class' => 'btn btn-success']) ?>
<?= $this->Form->button(__('Update Cart'), ['controller' => 'Carts', 'action' => 'updateCart'], ['class' => 'btn btn-success']) ?>
<?= $this->Form->end() ?>
<?= $this->Form->postLink(__('Clear Cart'), ['controller' => 'Carts', 'action' => 'clearCart'], ['class' => 'btn btn-danger', 'confirm' => __('Are you sure you want to clear your cart?')]) ?>
</section>
controller
public function updateCart()
{
if(isset($_SESSION['cart']) && !empty($_SESSION['cart'])){
if ($this->request->is('post')) {
$qty = $this->request->getData('quantity[]');
debug($this->request->getData('quantity'));
}
}
else{
$this->Flash->error(__("You don't have anything in your cart. Add more?"));
}
$this->redirect(['controller'=>'Carts','action' => 'index']);
}
Thank you

How to get 'selected' option value in edit mode with modal codeigniter 4

I have modal with options, i want to edit it, the value goes back like in create function. what i want to ask is how to get the value i've selected in edit function?
Here my model:
..................................................................................................
public function find_all()
{
return $this->db->table('tbl_barang')
->orderBy('id_barang', 'ASC')
->get()
->getResultArray();
}
public function get_kategori()
{
return $this->db->table('tbl_kategori')
->orderBy('id_kategori', 'ASC')
->get()
->getResultArray();
}
public function get_satuan()
{
return $this->db->table('tbl_satuan')
->orderBy('id_satuan', 'ASC')
->get()
->getResultArray();
}
public function join_kategori_satuan()
{
return $this->db->table('tbl_barang')
->join('tbl_kategori', 'tbl_kategori.id_kategori=tbl_barang.id_kategori')
->join('tbl_satuan', 'tbl_satuan.id_satuan=tbl_barang.id_satuan')
->get()
->getResultArray();
}
public function update_data($data)
{
$this->db->table('tbl_barang')
->where('id_barang', $data['id_barang'])
->update($data);
}
Here is my controller:
..................................................................................................
public function index()
{
$data = [
'title' => 'Goods',
'message' => 'Goods Page ',
'kategori' => $this->M_Category->get_kategori(),
'satuan' => $this->M_Item_Unit->get_satuan(),
'goods' => $this->M_Goods->find_all(),
'join_kategori_satuan' => $this->M_Goods->join_kategori_satuan(),
];
return view('content/goods/v_goods', $data);
}
public function edit_goods($id_barang)
{
if ($this->validate([
'foto_barang' => [
'rules' => 'max_size[foto_barang,1024]|is_image[foto_barang]|mime_in[foto_barang,image/jpg,image/jpeg,image/png]',
'errors' => [
'max_size' => 'Size max 1Mb!',
'is_image' => 'File not image!',
'mime_in' => 'File format must jpg/jpeg/png!',
]
],
])) {
$file = $this->request->getFile('foto_barang');
if ($file->getError() == 4) {
$data = [
'select_field_id' => $this->M_Goods->select_field_id($id_barang),
'id_barang' => $id_barang,
'id_kategori' => $this->request->getVar('id_kategori'),
'id_satuan' => $this->request->getVar('id_satuan'),
'nama_barang' => $this->request->getVar('nama_barang'),
'merk_barang' => $this->request->getVar('merk_barang'),
'stok_barang' => $this->request->getVar('stok_barang'),
];
$this->M_Goods->update_data($id_barang, $data);
} else {
$fotoLama = $this->M_Goods->change_photo($id_barang);
if ($fotoLama['foto_barang'] != "") {
unlink('./goods_photo/' . $fotoLama['foto_barang']);
}
$nama_file = $file->getRandomName();
$data = [
'id_barang' => $id_barang,
'id_kategori' => $this->request->getVar('id_kategori'),
'id_satuan' => $this->request->getVar('id_satuan'),
'nama_barang' => $this->request->getVar('nama_barang'),
'merk_barang' => $this->request->getVar('merk_barang'),
'stok_barang' => $this->request->getVar('stok_barang'),
'foto_barang' => $nama_file,
];
$file->move('goods_photo/', $nama_file);
$this->M_Goods->update_data($data);
}
session()->setFlashdata('success-edit', 'Goods Successfully Edited');
return redirect()->to('Goods');
} else {
session()->setFlashdata('errors', \Config\Services::validation()->getErrors());
return redirect()->to(base_url('Goods'));
}
}
Here my view:
..................................................................................................
<?php foreach ($goods as $key => $value) { ?>
<div class="modal fade" id="edit<?= $value['id_barang']; ?>">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit Item</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<?php echo form_open_multipart('Goods/edit_goods/' . $value['id_barang']) ?>
<?= csrf_field(); ?>
<div class="modal-body">
<div class="row">
<div class="col-sm-12">
<!-- THIS MY PROBLEM -->
<div class="form-group">
<label>Category Name</label>
<select name="id_kategori" class="form-control" required>
<option value="">-- Choose Category --</option>
<?php foreach ($kategori as $key => $value) { ?>
<option value="<?= $value['id_kategori'] ?>"> <?= $value['nama_kategori'] ?></option>
<?php } ?>
</select>
</div>
<div class="form-group">
<label>Item Unit Name</label>
<select name="id_satuan" class="form-control" required>
<option value="">-- Choose Item Unit --</option>
<?php foreach ($satuan as $key => $value) { ?>
<option value="<?= $value['id_satuan'] ?>"> <?= $value['nama_satuan'] ?></option>
<?php } ?>
</select>
</div>
<!-- /.THIS MY PROBLEM -->
</div>
</div>
</div>
<div class="modal-footer justify-content-between">
<button type="submit" class="btn btn-primary btn-sm">Save</button>
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">Close</button>
</div>
<?php echo form_close() ?>
</div>
</div>
</div>
<?php }; ?>
..................................................................................................
do it with jquery or js
$("#n").val('item');
$('.class').val('item');

How to show form fields while updating a record in Yii2

I am using wbraganca
/
yii2-dynamicform. I am able to create a new record. There are two models that I am using to create records. The data is saved into both of the tables.
<?= $form->field($model, 't_name')->textInput(['maxlength' => true]) ?>
<div class="row">
<div class="panel panel-default">
<div class="panel-heading"><h4><i class="glyphicon glyphicon-flash"></i> Tariff Slabs</h4></div>
<div class="panel-body">
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
'widgetBody' => '.container-items', // required: css class selector
'widgetItem' => '.item', // required: css class
'limit' => 10, // the maximum times, an element can be cloned (default 999)
'min' => 1, // 0 or 1 (default 1)
'insertButton' => '.js-add-filter', // css class
'deleteButton' => '.js-remove-filter', // css class
'model' => $modelsTariffSlabs[0],
'formId' => 'dynamic-form',
'formFields' => [
'slab_name',
'slab_start',
'slab_end',
'rate'
],
]); ?>
<div class="container-items"><!-- widgetContainer -->
<?php foreach ($modelsTariffSlabs as $i => $modelTariffSlabs): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<h3 class="panel-title pull-left">Slab</h3>
<div class="pull-right">
<button type="button" id="addBtn" class="js-add-filter btn btn-success btn-xs"><i class="glyphicon glyphicon-plus"></i></button>
<button type="button" id="remBtn" class="js-remove-filter btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
</div>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<?php
// necessary for update action.
if (! $modelTariffSlabs->isNewRecord) {
echo Html::activeHiddenInput($modelTariffSlabs, "[{$i}]id");
}
?>
<div class="row">
<div class="col-sm-3">
<?= $form->field($modelTariffSlabs, "[{$i}]slab_name")->textInput(['maxlength' => 10,"class"=>"form-control js-slab-name"]) ?>
</div>
<div class="col-sm-3">
<?= $form->field($modelTariffSlabs, "[{$i}]slab_start")->textInput(['maxlength' => 10,"class"=>"form-control js-slab-start"]) ?>
</div>
<div class="col-sm-3">
<?= $form->field($modelTariffSlabs, "[{$i}]slab_end")->textInput(['maxlength' => 10,"class"=>"form-control js-slab-end"]) ?>
</div>
<div class="col-sm-3">
<?= $form->field($modelTariffSlabs, "[{$i}]rate")->textInput(['maxlength' => 10]) ?>
</div>
</div><!-- .row -->
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
</div>
</div>
Now when I try to update it I am not data of the second model.
Update.php
<div class="mdc-tariff-update">
<?= $this->render('_form', [
'model' => $model,
'modelsTariffSlabs' => $modelsTariffSlabs
]) ?>
</div>
Update controller
public function actionUpdate($id)
{
$model = $this->findModel($id);
$modelsTariffSlabs = [new MdcTariffSlabs()];
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$oldIDs = ArrayHelper::map($modelsTariffSlabs, 'id', 'id');
$modelsTariffSlabs = CustomtariffModel::createMultiple(MdcTariffSlabs::classname(), $modelsTariffSlabs);
CustomtariffModel::loadMultiple($modelsTariffSlabs, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsTariffSlabs, 'id', 'id')));
// validate all models
$valid = $model->validate();
$valid = CustomtariffModel::validateMultiple($modelsTariffSlabs) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
if (! empty($deletedIDs)) {
MdcTariffSlabs::deleteAll(['id' => $deletedIDs]);
}
foreach ($modelsTariffSlabs as $modelTariffSlabs) {
$modelTariffSlabs->t_id = $model->id;
if (! ($flag = $modelTariffSlabs->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
return $this->redirect(['view', 'id' => $model->id]);
}
return $this->render('update', [
'model' => $model,
'modelsTariffSlabs' => (empty($modelsTariffSlabs)) ? [new MdcTariffSlabs()] : $modelsTariffSlabs
]);
}
How can I show the values of all fields in my update form ?
Any help would be highly appreaciated.
Or you can call relation like (when you are on update mode):
$modelsTariffSlabs = $model->mdcTariffSlabs
If mdcTariffSlabs is name of relation - it returns array if related models.
Or if you don't have relation, you can create it in main model:
public function getMdcTariffSlabs()
{
return $this->hasMany(MdcTariffSlabs::className(), ['t_id' => 'id']);
}
I assume that the issue is in this line
$modelsTariffSlabs = [new MdcTariffSlabs()];
It always create an empty model. You have to get all the records that are saved. Below code should work
Assuming that $modelTariffSlabs->t_id = $model->id; // t_id is id of your main table
protected function findModelSlabs($id)
{
if (($model = MdcTariffSlabs::find()->where(['t_id'=>$id])->all()) !== null) {
return $model;
}
throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
}
And then change
$modelsTariffSlabs = [new MdcTariffSlabs()];
TO
$modelsTariffSlabs = $this->findModelSlabs($model->id);
I hope this will help

Yii2: Undefined variable if $model = Model::find()->all(); is not specified in view

I have a view where I need to show both table of current records and search within the table. The problem is, that after a search action the table still shows all records, despite URL shows searching parameters. I suppose, that is because all records specified in model ($posts = Post::find()->all();).
But if I remove that string, I get an exception "Undefined variable: posts".
How can it be fixed?
Model:
class Post extends ActiveRecord
{
public static function tableName()
{
return 'post';
}
public $upload;
public function rules()
{
return [
[['desc'], 'required'],
[['desc'], 'string', 'max' => 255],
[['upload'], 'file'],
];
}
}
Controller:
public function actionSearch()
{
if (Yii::$app->request->get()){
$search = Yii::$app->request->get('search');
$query = Post::find()->where(['like', 'desc', $search]);
return $this->render('search', compact('query', 'search'));
} else {
$files = Post::find()->all();
return $this->render('search', ['files' => $files]);
}
}
View:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use app\models\Post;
$this->title = 'Search';
$posts = Post::find()->all();
?>
<div class="site-search card border-secondary">
<div class="card-header"><h3><?= Html::encode($this->title) ?></h3></div>
<?php $form = ActiveForm::begin([
'action' => ['search'],
'method' => 'get',
]) ?>
<div class="body-content card-body">
<div class="form-group row">
<label class="col-sm-4 col-form-label">Description</label>
<div class="col-sm-8">
<?= Html::textInput('search','', ['class' => 'form-control']) ?>
</div>
</div>
<div class="col-sm-offset-4">
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
</div>
<table class="table">
<thead>
<tr>
<th class="col-md-4">Name</th>
<th class="col-md-6">Description</th>
<th class="col-md-2">Action</th>
</tr>
</thead>
<tbody>
<?foreach ($posts as $post):?>
<tr>
<td class="hidden"><?=$post->id?></td>
<td><?=$post->file?></td>
<td><?=$post->desc?></td>
<td><?= Html::a('Download', ['download', 'id'=>$post->id]) ?></td>
</tr>
<?endforeach;?>
</tbody>
</table>
</div>
<?php ActiveForm::end() ?>
</div>
You need to pass $posts value to your view:
public function actionSearch() {
if (Yii::$app->request->get('search')){
$search = Yii::$app->request->get('search');
$posts = Post::find()->where(['like', 'desc', $search])->all();
} else {
$posts = Post::find()->all();
}
return $this->render('search', ['posts' => $posts]);
}
Then you can remove $posts = Post::find()->all(); from your view.
In view your refer to $posts but in actionSearch you use $files so
In your action change the $files in $posts
public function actionSearch()
{
if (Yii::$app->request->get()){
$search = Yii::$app->request->get('search');
$posts= Post::find()->where(['like', 'desc', $search]);
return $this->render('search', compact('query', 'search'));
} else {
$posts = Post::find()->all();
return $this->render('search', ['posts' => $posts]);
}
}
and then in view remove the $postes
$this->title = 'Search';
//$posts = Post::find()->all();
?>

Yii2-dynamicforms extension

I am new to yii2.0, and I'm currently creating a form po
and po_item, the problem is to update the form the modelPoItem is empty from database.
I thank those who can help me for this Home with dynamic form can be with an example. Thank you in advance
Po Controller
/**
* Updates an existing Po model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
$modelsPoItem = [new PoItem];
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
} else {
return $this->render('update', [
'model' => $model,
'modelsPoItem' => (empty($modelsPoItem)) ? [new PoItem] : $modelsPoItem
]);
}
}
View
<div class="po-form">
<?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>
<?= $form->field($model, 'po_no')->textInput(['maxlength' => 10]) ?>
<?= $form->field($model, 'description')->textarea(['rows' => 6]) ?>
<div class="row">
<div class="panel panel-default">
<div class="panel-heading"><h4><i class="glyphicon glyphicon-envelope"></i> Po Items</h4></div>
<div class="panel-body">
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
'widgetBody' => '.container-items', // required: css class selector
'widgetItem' => '.item', // required: css class
'limit' => 10, // the maximum times, an element can be cloned (default 999)
'min' => 1, // 0 or 1 (default 1)
'insertButton' => '.add-item', // css class
'deleteButton' => '.remove-item', // css class
'model' => $modelsPoItem[0],
'formId' => 'dynamic-form',
'formFields' => [
'po_item_no',
'quantity',
],
]); ?>
<div class="container-items"><!-- widgetContainer -->
<?php foreach ($modelsPoItem as $i => $modelPoItem): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<h3 class="panel-title pull-left">Po Item</h3>
<div class="pull-right">
<button type="button" class="add-item btn btn-success btn-xs"><i class="glyphicon glyphicon-plus"></i></button>
<button type="button" class="remove-item btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
</div>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<?php
// necessary for update action.
if (! $modelPoItem->isNewRecord) {
echo Html::activeHiddenInput($modelPoItem, "[{$i}]id");
}
?>
<div class="row">
<div class="col-sm-6">
<?= $form->field($modelPoItem, "[{$i}]po_item_no")->textInput(['maxlength' => 128]) ?>
</div>
<div class="col-sm-6">
<?= $form->field($modelPoItem, "[{$i}]quantity")->textInput(['maxlength' => 128]) ?>
</div>
</div><!-- .row -->
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
</div>
</div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
you should be change you update action like this:
public function actionUpdate($id)
{
$model = $this->findModel($id);
$modelsPoItem = $model->poItems;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$oldIDs = ArrayHelper::map($modelsPoItem, 'id', 'id');
$modelsPoItem= Model::createMultiple(PoItem::className(),$modelsPoItem);
Model::loadMultiple($modelsPoItem, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsPoItem, 'id', 'id')));
// ajax validation
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ArrayHelper::merge(
ActiveForm::validateMultiple($modelsPoItem),
ActiveForm::validate($model)
);
}
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsPoItem) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
if (! empty($deletedIDs)) {
PoItem::deleteAll(['id' => $deletedIDs]);
}
foreach ($modelsPoItem as $modelPoItem) {
$modelPoItem->po_id = $model->id;
if (! ( $flag = $modelPoItem->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
} else {
return $this->render('update', [
'model' => $model,
'modelsPoItem' => (empty($modelsPoItem)) ? [new Model] : $modelsPoItem
]);
}
}

Categories