I'm trying to update data with the help of yii2/dynamic form.
Table 1- "sellsg" - columns (ssg_id,ssg_customer,ssg_invoiceno,ssg_date,ssg_amount)
Table2 - "sellitemsg" - columns (ssgi_id,ssgi_invoiceno,ssgi_sgname,ssgi_price)
Relation - sellsg.ssg_invoiceno = sellitemsg.ssgi_invoiceno
The Create part is working fine. I'm struggling with the update part.
Problem 1.
When the form was creating new record - There is a javascript code in the form to increase the invoice no by 1 everytime. When I'm loading the form for update, it also increases in by 1 overriding the original invoiceno. I want to limit this function only when I create but not in update.
Problem 2
When I am updating the form, it only updating the sellsg table but not sellitemsg table.
_Form
<?php
use yii\helpers\Html;
use kartik\form\ActiveForm;
use wbraganca\dynamicform\DynamicFormWidget;
use dosamigos\datepicker\DatePicker;
use yii\helpers\ArrayHelper;
use kartik\select2\Select2;
use frontend\modules\sellsg\models\Customer;
use frontend\modules\sellsg\models\Sunglass;
/* #var $this yii\web\View */
/* #var $model frontend\modules\sellsg\models\Sellsg */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="sellsg-form">
<?php $form = ActiveForm::begin([
'id' => 'dynamic-form',
'type' => ActiveForm::TYPE_HORIZONTAL,
'formConfig' => ['labelSpan' => 3, 'deviceSize' => ActiveForm::SIZE_SMALL]
]);
?>
<div class="row">
<div class="col-xs-12 col-sm-12 col-lg-12">
<div class="form-group">
<div class="col-xs-6 col-sm-6 col-lg-6">
<?= $form->field($model, 'ssg_customer')->label(false)->widget(Select2::classname(), [
'data' => ArrayHelper::map(Customer::find()->all(),'c_name','customerDetails'),
'language' => 'en',
'options' => ['placeholder' => 'Select Customer Details', 'id' => 'custid'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($model, 'ssg_date')->widget(
DatePicker::className(), [
// inline too, not bad
'inline' => false,
// modify template for custom rendering
//'template' => '<div class="well well-sm" style="background-color: #fff; width:250px">{input}</div>',
'clientOptions' => [
'autoclose' => true,
'todayHighlight' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
</div>
</div>
</div>
</div>
<?= $form->field($model, 'ssg_invoiceno')->textInput() ?>
<div class="rows">
<div class="panel panel-default">
<div class="panel-heading"><h4><i class="glyphicon glyphicon-envelope"></i> Sunglasses</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' => 20, // 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' => $modelsSellitemsg[0],
'formId' => 'dynamic-form',
'formFields' => [
'ssgi_sgname',
'ssgi_price',
],
]); ?>
<div class="container-items"><!-- widgetContainer -->
<?php foreach ($modelsSellitemsg as $i => $modelSellitemsg): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-body">
<?php
// necessary for update action.
if (! $modelSellitemsg->isNewRecord) {
echo Html::activeHiddenInput($modelSellitemsg, "[{$i}]ssgi_id");
}
?>
<div class="row">
<div class="col-sm-6">
<?= $form->field($modelSellitemsg, "[{$i}]ssgi_sgname")->label(false)->widget(Select2::classname(), [
'data' => ArrayHelper::map(Sunglass::find()->all(),'sg_name','sg_name'),
'language' => 'en',
'options' => ['placeholder' => 'Select Sunglass'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
</div>
<div class="col-sm-3">
<?= $form->field($modelSellitemsg, "[{$i}]ssgi_price")->textInput([
'maxlength' => true,
'class' => 'sumPart',
//'onfocus'=>'sum()', 'onBlur'=>'sum()'
]) ?>
</div>
<div class="col-sm-3">
<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>
</div><!-- .row -->
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-lg-12">
<div class="form-group">
<div class="col-xs-6 col-sm-6 col-lg-6">
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($model, 'ssg_amount')->textInput(['class' => 'sum']) ?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-lg-12">
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
/* start getting the invoiceno */
$script = <<<EOD
$(window).load(function(){
$.get('get-for-invoiceno',{ invoiceid : 1 }, function(data){
//alert(data);
var data = $.parseJSON(data);
$('#sellsg-ssg_invoiceno').attr('value',data.invoiceno);
}
);
});
EOD;
$this->registerJs($script);
/*end getting the invoiceno */
?>
<?php
/* start getting the totalamount */
$script = <<<EOD
var getSum = function() {
var items = $(".item");
var sum = 0;
items.each(function (index, elem) {
var priceValue = $(elem).find(".sumPart").val();
//Check if priceValue is numeric or something like that
sum = parseInt(sum) + parseInt(priceValue);
});
//Assign the sum value to the field
$(".sum").val(sum);
};
//Bind new elements to support the function too
$(".container-items").on("change", ".sumPart", function() {
getSum();
});
EOD;
$this->registerJs($script);
/*end getting the totalamount */
?>
SellsgController
public function actionCreate()
{
$model = new Sellsg();
$modelsSellitemsg = [new Sellitemsg];
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$modelsSellitemsg = Model::createMultiple(Sellitemsg::classname());
Model::loadMultiple($modelsSellitemsg, Yii::$app->request->post());
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsSellitemsg) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
foreach ($modelsSellitemsg as $modelSellitemsg) {
$modelSellitemsg->ssgi_invoiceno = $model->ssg_invoiceno;
if (! ($flag = $modelSellitemsg->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->ssg_id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
else {
return $this->render('create', [
'model' => $model,
'modelsSellitemsg' => (empty($modelsSellitemsg)) ? [new Sellitemsg] : $modelsSellitemsg
]);
}
}
/**
* Updates an existing Sellsg 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);
$modelsSellitemsg = $model->sellitemsg;
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$oldIDs = ArrayHelper::map($modelsSellitemsg, 'id', 'id');
//var_dump($oldIDs);
$modelsSellitemsg = Model::createMultiple(Sellitemsg::classname(), $modelsSellitemsg);
Model::loadMultiple($modelsSellitemsg, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsSellitemsg, 'id', 'id')));
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsSellitemsg) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
if (! empty($deletedIDs)) {
Sellitemsg::deleteAll(['id' => $deletedIDs]);
}
foreach ($modelsSellitemsg as $modelSellitemsg) {
$modelSellitemsg->ssgi_invoiceno = $model->ssg_invoiceno;
if (! ($flag = $modelSellitemsg->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->ssg_id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
else {
return $this->render('update', [
'model' => $model,
'modelsSellitemsg' => (empty($modelsSellitemsg)) ? [new Sellitemsg] : $modelsSellitemsg
]);
}
}
sellsg model
<?php
namespace frontend\modules\sellsg\models;
use Yii;
/**
* This is the model class for table "sellsg".
*
* #property integer $ssg_id
* #property string $ssg_customer
* #property integer $ssg_invoiceno
* #property string $ssg_date
* #property integer $ssg_amount
*/
class Sellsg extends \yii\db\ActiveRecord
{
public $modelsSellitemsg;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'sellsg';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['ssg_customer', 'ssg_invoiceno', 'ssg_date', 'ssg_amount'], 'required'],
[['ssg_invoiceno', 'ssg_amount'], 'integer'],
[['ssg_customer'], 'string', 'max' => 200],
[['ssg_invoiceno'], 'unique'],
[['ssg_date'], 'string', 'max' => 10],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'ssg_id' => 'ID',
'ssg_customer' => 'Customer',
'ssg_invoiceno' => 'Invoice No',
'ssg_date' => 'Date',
'ssg_amount' => 'Amount',
];
}
public function getSellitemsg()
{
return $this->hasMany(Sellitemsg::className(), ['ssgi_invoiceno' => 'ssg_invoiceno']);
}
}
update.php
<?php
use yii\helpers\Html;
/* #var $this yii\web\View */
/* #var $model frontend\modules\sellsg\models\Sellsg */
$this->title = 'Update Sellsg: ' . $model->ssg_id;
$this->params['breadcrumbs'][] = ['label' => 'Sellsgs', 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => $model->ssg_id, 'url' => ['view', 'id' => $model->ssg_id]];
$this->params['breadcrumbs'][] = 'Update';
?>
<div class="sellsg-update">
<h1><?= Html::encode($this->title) ?></h1>
<?= $this->render('_form', [
'model' => $model,
'modelsSellitemsg' => $modelsSellitemsg,
]) ?>
</div>
With the current code I'm getting error
Getting unknown property: frontend\modules\sellsg\models\Sellitemsg::id
I've found the solution
Problem1 -
I've created _updateform.php and redirected to update from there and removed the javascript to load invoicno -
Update.php
<?php
use yii\helpers\Html;
/* #var $this yii\web\View */
/* #var $model frontend\modules\sellsg\models\Sellsg */
$this->title = 'Update InvoiceNo: ' . $model->ssg_id;
$this->params['breadcrumbs'][] = ['label' => 'Sellsgs', 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => $model->ssg_id, 'url' => ['view', 'id' => $model->ssg_id]];
$this->params['breadcrumbs'][] = 'Update';
?>
<div class="sellsg-update">
<h1><?= Html::encode($this->title) ?></h1>
<?= $this->render('_updateform', [
'model' => $model,
'modelsSellitemsg' => $modelsSellitemsg,
]) ?>
</div>
Problem2
My actionUpdate code now looks like -
public function actionUpdate($id)
{
$model = $this->findModel($id);
$modelsSellitemsg = $model->sellitemsg;
//$model->setScenario('update');
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$oldIDs = ArrayHelper::map($modelsSellitemsg, 'ssgi_id', 'ssgi_id');
//var_dump($oldIDs);
$modelsSellitemsg = Model::createMultiple(Sellitemsg::classname(), $modelsSellitemsg);
Model::loadMultiple($modelsSellitemsg, Yii::$app->request->post());
$deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsSellitemsg, 'ssgi_id', 'ssgi_id')));
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsSellitemsg) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
if (! empty($deletedIDs)) {
Sellitemsg::deleteAll(['ssgi_id' => $deletedIDs]);
}
foreach ($modelsSellitemsg as $modelSellitemsg) {
$modelSellitemsg->ssgi_invoiceno = $model->ssg_invoiceno;
if (! ($flag = $modelSellitemsg->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->ssg_id]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
}
else {
return $this->render('update', [
'model' => $model,
'modelsSellitemsg' => (empty($modelsSellitemsg)) ? [new Sellitemsg] : $modelsSellitemsg
]);
}
}
/**
* Deletes an existing Sellsg model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
and Model.php -
<?php
namespace frontend\modules\sellsg\models;
use Yii;
use yii\helpers\ArrayHelper;
class Model extends \yii\base\Model
{
/**
* Creates and populates a set of models.
*
* #param string $modelClass
* #param array $multipleModels
* #return array
*/
public static function createMultiple($modelClass, $multipleModels = [])
{
$model = new $modelClass;
$formName = $model->formName();
$post = Yii::$app->request->post($formName);
$models = [];
if (! empty($multipleModels)) {
$keys = array_keys(ArrayHelper::map($multipleModels, 'ssgi_id', 'ssgi_id'));
$multipleModels = array_combine($keys, $multipleModels);
}
if ($post && is_array($post)) {
foreach ($post as $i => $item) {
if (isset($item['ssgi_id']) && !empty($item['ssgi_id']) && isset($multipleModels[$item['ssgi_id']])) {
$models[] = $multipleModels[$item['ssgi_id']];
} else {
$models[] = new $modelClass;
}
}
}
unset($model, $formName, $post);
return $models;
}
}
And Is working fine now.
Related
I refer to this link https://github.com/jaradsee/faktharm/blob/master/controllers/PhotoLibraryController.php
to upload multiple images but when I try to delete the selected image in update form it showing me these error
(image1)
(image2)
For image 2, why the url link always give products%252Fdeletefile-ajax (give number 25)
Below is my code, please help me to check what's goes wrong, thank you!
Uploads.php
class Uploads extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'uploads';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['file_name'], 'required'],
[['upload_id'], 'integer'],
[['create_date'], 'safe'],
[['ref'], 'string', 'max' => 100],
[['file_name', 'real_filename'], 'string', 'max' => 150],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'upload_id' => 'Upload ID',
'ref' => 'Ref',
'file_name' => 'File Name',
'real_filename' => 'Real Filename',
'create_date' => 'Create Date',
];
}
}
Products.php
class Products extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
//public $file;
const UPLOAD_FOLDER='products';
public static function tableName()
{
return 'products';
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['productName', 'productDescription', 'productPrice', 'categoryId', 'brandId', 'productStatus'], 'required'],
[['productDescription', 'productStatus'], 'string'],
[['productPrice'], 'number'],
[['categoryId', 'brandId'], 'integer'],
[['productName','ref'], 'string', 'max' => 100],
[['brandId'], 'exist', 'skipOnError' => true, 'targetClass' => Brands::className(), 'targetAttribute' => ['brandId' => 'brandId']],
[['categoryId'], 'exist', 'skipOnError' => true, 'targetClass' => Categorys::className(), 'targetAttribute' => ['categoryId' => 'categoryId']],
[['ref'],'unique']
// ['productImage', 'file','maxFiles'=>5],
//[['file'],'productImage']
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'productId' => 'Product ID',
'productName' => 'Product Name',
'productDescription' => 'Product Description',
'productPrice' => 'Product Price',
'ref' => 'Product Image',
'categoryId' => 'Category',
'brandId' => 'Brand',
'productStatus' => 'Product Status',
];
}
/**
* Gets query for [[Brand]].
*
* #return \yii\db\ActiveQuery
*/
public function getBrand()
{
return $this->hasOne(Brands::className(), ['brandId' => 'brandId']);
}
/**
* Gets query for [[Category]].
*
* #return \yii\db\ActiveQuery
*/
public function getCategory()
{
return $this->hasOne(Categorys::className(), ['categoryId' => 'categoryId']);
}
public function getImages()
{
return $this->hasMany(Images::className(), ['productId' => 'productId']);
}
public static function getUploadPath(){
return Yii::getAlias('#webroot').'/'.self::UPLOAD_FOLDER.'/';
}
public static function getUploadUrl(){
return Url::base(true).'/'.self::UPLOAD_FOLDER.'/';
}
public function getThumbnails($ref,$event_name){
$uploadFiles = Uploads::find()->where(['ref'=>$ref])->all();
$preview = [];
foreach ($uploadFiles as $file) {
$preview[] = [
'url'=>self::getUploadUrl(true).$ref.'/'.$file->real_filename,
'src'=>self::getUploadUrl(true).$ref.'/thumbnail/'.$file->real_filename,
'options' => ['title' => $event_name]
];
}
return $preview;
}
}
ProductsController.php
namespace backend\controllers;
use Yii;
use backend\models\Products;
use backend\models\Uploads;
use backend\models\ProductsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use yii\helpers\Json;
use yii\widgets\ActiveForm;
use yii\web\UploadedFile;
use yii\helpers\Url;
use yii\helpers\html;
use yii\helpers\BaseFileHelper;
use yii\helpers\ArrayHelper;
/**
* ProductsController implements the CRUD actions for Products model.
*/
class ProductsController extends Controller
{
/**
* {#inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
// 'access' => [
// 'class' => AccessControl::className(),
// 'rules' => [
// [
// 'actions' => ['view','update','_form','index','_search','create','uploadAjax','createDir'],
// 'allow' => true,
// 'roles' => ['admin'],
// ],
// ],
// ],
];
}
/**
* Lists all Products models.
* #return mixed
*/
public function actionIndex($pageSize = 10)
{
$searchModel = new ProductsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams, $pageSize);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'pageSize' => $pageSize,
]);
}
/**
* Displays a single Products model.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Products model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
/*public function actionCreate()
{
$model = new Products();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$model->imageFiles = UploadedFile::getInstances($model, 'productImage');
return $this->redirect(['view', 'id' => $model->productId]);
}
return $this->render('create', [
'model' => $model,
]);
}*/
public function actionCreate()
{
$model = new Products();
if ($model->load(Yii::$app->request->post())) {
$this->Uploads(false);
if($model->save()){
return $this->redirect(['view', 'id' => $model->productId]);
}
}
else{
$model->ref = substr(Yii::$app->getSecurity()->generateRandomString(),10);
}
return $this->render('create', [
'model' => $model,
]);
}
/**
* Updates an existing Products model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
list($initialPreview,$initialPreviewConfig) = $this->getInitialPreview($model->ref);
if ($model->load(Yii::$app->request->post())) {
$this->Uploads(false);
if($model->save()){
return $this->redirect(['view', 'id' => $model->productId]);
}
}
return $this->render('update', [
'model' => $model,
'initialPreview'=>$initialPreview,
'initialPreviewConfig'=>$initialPreviewConfig
]);
}
/**
* Deletes an existing Products model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param integer $id
* #return mixed
* #throws NotFoundHttpException if the model cannot be found
*/
public function actionDelete($id)
{
//$model = new Products();
//$this->findModel($id)->delete();
$model->$this->findModel($id);
$this->removeUploadDir($model->ref);
Uploads::deleteAll(['ref'=>$model->ref]);
$model->delete();
return $this->redirect(['index']);
}
/**
* Finds the Products model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Products the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Products::findOne($id)) !== null) {
return $model;
}
throw new NotFoundHttpException('The requested page does not exist.');
}
/*|*********************************************************************************|
|================================ Upload Ajax ====================================|
|*********************************************************************************|*/
public function actionUploadAjax(){
$this->Uploads(true);
}
private function CreateDir($folderName){
if($folderName != NULL){
$basePath = Products::getUploadPath();
if(BaseFileHelper::createDirectory($basePath.$folderName,0777)){
BaseFileHelper::createDirectory($basePath.$folderName.'/thumbnail',0777);
}
}
return;
}
private function removeUploadDir($dir){
BaseFileHelper::removeDirectory(Products::getUploadPath().$dir);
}
private function Uploads($isAjax=false) {
if (Yii::$app->request->isPost) {
$images = UploadedFile::getInstancesByName('upload_ajax');
if ($images) {
if($isAjax===true){
$ref =Yii::$app->request->post('ref');
}else{
$Products = Yii::$app->request->post('Products');
$ref = $Products['ref'];
}
$this->CreateDir($ref);
foreach ($images as $file){
$fileName = $file->baseName . '.' . $file->extension;
$realFileName = md5($file->baseName.time()) . '.' . $file->extension;
$savePath = Products::UPLOAD_FOLDER.'/'.$ref.'/'. $realFileName;
if($file->saveAs($savePath)){
if($this->isImage(Url::base(true).'/'.$savePath)){
$this->createThumbnail($ref,$realFileName);
}
$model = new Uploads;
$model->ref = $ref;
$model->file_name = $fileName;
$model->real_filename = $realFileName;
$model->save();
if($isAjax===true){
echo json_encode(['success' => 'true']);
}
}else{
if($isAjax===true){
echo json_encode(['success'=>'false','eror'=>$file->error]);
}
}
}
}
}
}
private function getInitialPreview($ref) {
$datas = Uploads::find()->where(['ref'=>$ref])->all();
$initialPreview = [];
$initialPreviewConfig = [];
foreach ($datas as $key => $value) {
array_push($initialPreview, $this->getTemplatePreview($value));
array_push($initialPreviewConfig, [
'caption'=> $value->file_name,
'width' => '120px',
'url' => Url::to(['/products/deletefile-ajax']),
'key' => $value->upload_id
]);
}
return [$initialPreview,$initialPreviewConfig];
}
public function isImage($filePath){
return #is_array(getimagesize($filePath)) ? true : false;
}
private function getTemplatePreview(Uploads $model){
$filePath = Products::getUploadUrl().$model->ref.'/thumbnail/'.$model->real_filename;
$isImage = $this->isImage($filePath);
if($isImage){
$file = Html::img($filePath,['class'=>'file-preview-image', 'alt'=>$model->file_name, 'title'=>$model->file_name]);
}else{
$file = "<div class='file-preview-other'> " .
"<h2><i class='glyphicon glyphicon-file'></i></h2>" .
"</div>";
}
return $file;
}
private function createThumbnail($folderName,$fileName,$width=250){
$uploadPath = Products::getUploadPath().'/'.$folderName.'/';
$file = $uploadPath.$fileName;
$image = Yii::$app->image->load($file);
$image->resize($width);
$image->save($uploadPath.'thumbnail/'.$fileName);
return;
}
public function actionDeletefileAjax(){
$model = Uploads::findOne(Yii::$app->request->post('key'));
if($model!==NULL){
$filename = Products::getUploadPath().$model->ref.'/'.$model->real_filename;
$thumbnail = Products::getUploadPath().$model->ref.'/thumbnail/'.$model->real_filename;
if($model->delete()){
#unlink($filename);
#unlink($thumbnail);
echo json_encode(['success'=>true]);
}else{
echo json_encode(['success'=>false]);
}
}else{
echo json_encode(['success'=>false]);
}
}
}
_form.php
<?php
//use kartik\file\FileInput;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use backend\models\Brands;
use backend\models\Categorys;
use yii\helpers\Url;
use kartik\file\FileInput;
/* #var $this yii\web\View */
/* #var $model backend\models\Products */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="photo-library-form">
<?php $form = ActiveForm::begin(['options'=>['enctype'=>'multipart/form-data']]); ?>
<?php $form->errorSummary($model) ?>
<?= $form->field($model, 'ref')->hiddenInput(['maxlength' => 100])->label(false); ?>
<?= $form->field($model, 'productName')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'productDescription')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'productPrice')->textInput() ?>
<?=
$form->field($model, 'brandId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Brands::find()->where(['brandStatus'=>'active'])->all(),'brandId','brandName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a brand ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?=
$form->field($model, 'categoryId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Categorys::find()->where(['categoryStatus'=>'active'])->all(),'categoryId','categoryName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a category ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?= $form->field($model, 'productStatus')->dropDownList([ 'active' => 'Active', 'inactive' => 'Inactive', ], ['prompt' => 'Status']) ?>
<div class="form-group field-upload_files">
<label class="control-label" for="upload_files[]"> Product Images </label>
<div>
<?=
FileInput::widget([
'name' => 'upload_ajax[]',
//'attribute'=>'productImage[]',
//'name'=>'productImage[]',
'options' => [
'multiple'=>true,
'accept' => 'image/*',
//'id'=>'imageId',
],
'pluginOptions' => [
'initialPreview'=> $initialPreview,
'initialPreviewConfig'=> $initialPreviewConfig,
'deleteUrl'=>Url::to(['/products/deletefile-ajax']),
'showPreview' => true,
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'uploadAsync' => true,
'uploadUrl'=>Url::to(['/products/upload-ajax']),
'maxFileCount' => 5,
'allowedFileExtensions' => ['jpg', 'png','jpeg'],
'previewFileType' => ['jpg', 'png','jpeg'],
'overwriteInitial'=>false,
'uploadExtraData' => [
'ref'=>$model->ref
],
'msgUploadBegin' => Yii::t('app', 'Please wait, system is uploading the files'),
'validateInitailCount'=>true,
'layoutTemplates'=>[
'actionZoom'=>'<button type="button" class="kv-file-zoom">{zoomIcon}</button>',
'actionUpload'=>'',
//'actionDelete'=>'<a>jj</a>',
//'footer' => '<div class="file-thumbnail-footer"><div class="file-caption-name" style="width:{width}">{caption}{size}</div>
//{progress}{actions}',
//'footer' => '<div class="file-thumbnail-footer"> <div class="file-caption-caption" title="{caption}"</div>'
//'actionDelete'=>'<button type="button" class="kv-file-remove"> {dataKey}{deleteUrl} {removeIcon}</button>',
],
],
'pluginEvents' => [
'filebatchselected' => 'function(event, files) {
$(this).fileinput("/products/upload-ajax");
}',
],
]);
?>
<br>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord? 'Save': 'Update', ['class' => 'btn btn-primary']) ?>
<?= Html::a(Yii::t('app', 'Cancel'), ['index', 'id' => $model->productId], ['class'=>'btn btn-danger']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
I found the solution my bad
need to change all the Url::to() in controller and _form
to this format solution
The detail answer as below
_form.php
<?php
//use kartik\file\FileInput;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use backend\models\Brands;
use backend\models\Categorys;
use yii\helpers\Url;
use kartik\file\FileInput;
/* #var $this yii\web\View */
/* #var $model backend\models\Products */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="photo-library-form">
<?php $form = ActiveForm::begin(['options'=>['enctype'=>'multipart/form-data']]); ?>
<?php $form->errorSummary($model) ?>
<?= $form->field($model, 'ref')->hiddenInput(['maxlength' => 100])->label(false); ?>
<?= $form->field($model, 'productName')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'productDescription')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'productPrice')->textInput() ?>
<?=
$form->field($model, 'brandId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Brands::find()->where(['brandStatus'=>'active'])->all(),'brandId','brandName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a brand ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?=
$form->field($model, 'categoryId')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Categorys::find()->where(['categoryStatus'=>'active'])->all(),'categoryId','categoryName'),
'language' => 'en',
'options' => ['placeholder' => 'Select a category ...'],
'pluginOptions' => [
'allowClear' => true
],
]);
?>
<?= $form->field($model, 'productStatus')->dropDownList([ 'active' => 'Active', 'inactive' => 'Inactive', ], ['prompt' => 'Status']) ?>
<label>Product Images</label>
<?=
FileInput::widget([
'name' => 'upload_ajax[]',
//'attribute'=>'productImage[]',
//'name'=>'productImage[]',
'options' => [
'multiple'=>true,
'accept' => 'image/*',
//'id'=>'imageId',
],
'pluginOptions' => [
'initialPreview'=> $initialPreview,
'initialPreviewConfig'=> $initialPreviewConfig,
'showPreview' => true,
'showCaption' => false,
'showRemove' => false,
'showUpload' => false,
'uploadAsync' => false,
'uploadUrl'=>Url::to('index.php?r=products/upload-ajax'),
'deleteUrl'=>Url::to('index.php?r=products/deletefile-ajax'),
'maxFileCount' => 5,
'allowedFileExtensions' => ['jpg', 'png','jpeg'],
'previewFileType' => ['jpg', 'png','jpeg'],
'overwriteInitial'=>false,
'enableResumableUpload'=>true,
'uploadExtraData' => [
'ref'=>$model->ref
],
'validateInitialCount'=>true,
'initialPreviewShowDelete' => true,
'layoutTemplates'=>[
'actionZoom'=>'<button type="button" class="kv-file-zoom">{zoomIcon}</button>',
'actionUpload'=>'',
'actionDelete' => '<button type="button" class="kv-file-remove" title="{removeTitle}" {dataKey}{dataUrl}><i class="glyphicon glyphicon-trash"></i></button>'
],
],
'pluginEvents' => [
// 'filebatchselected' => 'function(files) {
// $(this).fileinput("index.php?r=products/upload-ajax");
// }',
'filepredelete'=>'function(jqXHR){
var abort = true;
if (confirm("Are you sure you want to delete this image?")) {
abort = false;
}
return abort;
}'
],
]);
?>
<br>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord? 'Save': 'Update', ['class' => 'btn btn-primary']) ?>
<?= Html::a(Yii::t('app', 'Cancel'), ['index', 'id' => $model->productId], ['class'=>'btn btn-danger']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
ProductsController
private function getInitialPreview($ref) {
$datas = Uploads::find()->where(['ref'=>$ref])->all();
$initialPreview = [];
$initialPreviewConfig = [];
foreach ($datas as $key => $value) {
array_push($initialPreview, $this->getTemplatePreview($value));
array_push($initialPreviewConfig, [
'caption'=> $value->file_name,
'width' => '120px',
'url' => Url::to('index.php?r=products/deletefile-ajax'),
'key' => $value->upload_id
]);
}
return [$initialPreview,$initialPreviewConfig];
}
I m new in yii2 framework, when I submit my Activeform data to save in database in display error
Not Found (#404).
This Activeform mention in different model view. My form is on product page and I want just give review of customer regarding this product and save in DB.
view file: detail.php:
<?php
use yii\helpers\Html;
use yii\widgets\DetailView;
use yii\widgets\ActiveForm;
/* #var $this yii\web\View */
/* #var $model app\models\Product */
$name = $result->name;
$price = $result->price;
$offerrate = 8;
$offer = ($price / 100) * $offerrate;
$offerprice = number_format($price - $offer, 2);
$text = $result->Description;
$list = explode(",", $text);
?>
<div id="page-content" class="home-page">
<div class="container">
<div class="row">
<div class="col-lg-5">
<center>
<?= Html::img(Yii::$app->urlManagerBackend->BaseUrl.'/'.$result->image, ['alt'=>'myImage','width'=>'300','height'=>'300', 'class' => 'img-responsive']) ?>
<br/>
<?= Html::button('ADD TO CART', ['class' => 'btn btn-success', 'id'=>'addcart']) ?>
<?= Html::button('BUY NOW', ['class' => 'btn btn-danger', 'id'=>'buynow']) ?>
</center>
</div>
<div class="col-lg-7">
<?php echo "<h5 style='color:#009933'>".$name."</h5>"?><br/>
<?php
echo "<ul>";
foreach ($list as $lists)
{
echo "<li class='liststyle'>".$lists."</li>";
}
echo "</ul>";
?><br/>
<?php echo "<h6 style='color:#009933'>MobileShop Offer Price Rs: ".$offerprice."</h6>" ?>
<?= Html::button('Rate and Review product', ['class' => 'btn btn-default', 'id'=>'review', 'data-toggle' => 'collapse', 'data-target' => '#demo']) ?>
<div id="demo" class="collapse">
<?php $form = ActiveForm::begin(['id' => 'reviewForm', 'action' => Yii::$app->urlManager->createUrl(['TblFeedback/create'])]); ?>
<?= $form->field($feedback, 'cust_name')->textInput() ?>
<?= $form->field($feedback, 'feedback')->textArea(['rows' => '2', 'cols' => '10'])?>
<?= $form->field($feedback, 'rating')->dropDownlist(['1' => '*', '2' => '* *', '3' => '* * *', '4' => '* * * *', '5' => '* * * * *']) ?>
<div class="form-group">
<?= Html::submitButton('Save', ['id' => 'savebtn', 'class' => 'btn btn-default']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
</div>
</div>
Controller file: TblFeedbackController.php
<?php
namespace frontend\controllers;
use Yii;
use app\models\TblFeedback;
use frontend\models\Product;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
class TblFeedbackController extends \yii\web\Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
public function actionIndex()
{
return $this->render('index');
}
public function actionCreate()
{
$feedback = new TblFeedback();
if ($feedback->load(Yii::$app->request->post()) && $feedback->validate())
{
var_dump($feedback);
die();
$feedback->save();
Yii::$app->session->setFlash('success', '<h5>Thanks for review!</h5>');
return $this->redirect(['index']);
}
else {
return $this->render('index',
['feedback' => $feedback,
]);
Yii::$app->session->setFlash('error', 'Error Found!');
}
}
}
model file: TblFeedback.php
<?php
namespace frontend\models;
use Yii;
/**
* This is the model class for table "tbl_feedback".
*
* #property integer $id
* #property integer $product_id
* #property integer $cust_id
* #property string $cust_name
* #property integer $rating
* #property string $feedback
*
* #property Product $product
* #property User $cust
*/
class TblFeedback extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'tbl_feedback';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['product_id', 'cust_id', 'cust_name', 'rating', 'feedback'], 'required'],
[['product_id', 'cust_id', 'rating'], 'integer'],
[['rating'], 'integer', 'min' => 1, 'max' => 5],
[['cust_name'], 'string', 'max' => 200],
[['feedback'], 'string', 'max' => 1000],
[['product_id'], 'exist', 'skipOnError' => true, 'targetClass' => Product::className(), 'targetAttribute' => ['product_id' => 'id']],
[['cust_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['cust_id' => 'id']],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'product_id' => 'Product ID',
'cust_id' => 'Cust ID',
'cust_name' => 'Enter Name:',
'rating' => 'Rating',
'feedback' => 'Description',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getProduct()
{
return $this->hasOne(Product::className(), ['id' => 'product_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCust()
{
return $this->hasOne(User::className(), ['id' => 'cust_id']);
}
}
The naming convention for controller action are based on - separator when a part is uppercase so you should use
<?php $form = ActiveForm::begin(['id' => 'reviewForm',
'action' => Yii::$app->urlManager->createUrl(['Tbl-feedback/create'])]); ?>
the naming convention,for the controllers, it is to start with a lowercase character.
so you should use
class tblFeedbackController extends \yii\web\Controller
and
<?php $form = ActiveForm::begin(['id' => 'reviewForm',
'action' => Yii::$app->urlManager->createUrl(['tbl-feedback/create'])]); ?>
and last suggestion you could use urlHelper
use yii\helpers\Url;
<?php $form = ActiveForm::begin(['id' => 'reviewForm',
'action' => Url::to(['tbl-feedback/create'])]); ?>
I cannot save all records but just the last.
In a form users insert Year_begin and Year_end
A variable $years (where $years = Year_end - Year_begin) is passed to the dynamic form.
Example:
Worked 2010 and 2011 I need to generate two records
Worked from 2010 to 2015 I need to generate six records
I don't want to use "+" and "-" button to generate new record.
Every record shows the correct YEAR value
This is the result:
This is the code of my form with while cycle:
<?php foreach ($modelsComm as $i => $modelComm): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<h3 class="panel-title pull-left">id_calcolo</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">
<!-- loop begin -->
<?php
$n=0;
while ($n < $years) {
// necessary for update action.
if (! $modelComm->isNewRecord) {
echo Html::activeHiddenInput($modelComm, "[{$i}]id");
}
?>
<div class="row">
<div class="col-sm-2">
<?= $form->field($modelComm, "[{$i}]year")->textInput(['value' => $year_begin+$n]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelComm, "[{$i}]worked")->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-4">
<?= $form->field($modelComm, "[{$i}]paid")->textInput(['maxlength' => true]) ?>
</div>
</div><!-- .row -->
<?php
$n++;
}
?>
<!-- loop end -->
</div>
</div>
<?php endforeach; ?>
My Controller function:
public function actionCreate($years,$year_begin)
{
$model = new CalcReference();
$modelsComm = [new Comm];
if ($model->load(Yii::$app->request->post()) && $model->save())
{
$modelsComm = Model::createMultiple(Comm::classname());
Model::loadMultiple($modelsComm, Yii::$app->request->post());
// ajax validation
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ArrayHelper::merge(
ActiveForm::validateMultiple($modelsComm),
ActiveForm::validate($model)
);
}
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsComm) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
foreach ($modelsComm as $modelComm) {
$modelComm->id_pratica = $model->id;
if (! ($flag = $modelComm->save(false))) {
$transaction->rollBack();
break;
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view',
'id' => $model->id,
'year_begin' => $yeear_begin,
'years' => $years,
]);
}
} catch (Exception $e) {
$transaction->rollBack();
}
}
/* return $this->redirect(['view', 'id' => $model->id,
'anno_inizio' => $anno_inizio,
'qta_anni' => $qta_anni,
'dal' => $dal,
'al' => $al,
'id_pratica' => $id_pratica,
]);*/
} else
{
return $this->render('create', [
'model' => $model,
'modelsComm' => (empty($modelsComm)) ? [new Comm] : $modelsComm,
'year_begin' => $yeear_begin,
'years' => $years,
]);
}
}
My model:
public static function tableName()
{
return 'comm';
}
public function rules()
{
return [
[['year', 'worked', ], 'required'],
[['worked', 'paid'], 'integer'],
];
}
public function attributeLabels()
{
return [
'id' => 'ID',
'year' => 'Year',
'worked' => 'Worked days',
'paid' => 'Total Paid',
];
}
This is model Model.php:
class Model extends \yii\base\Model
{
/**
* Creates and populates a set of models.
*
* #param string $modelClass
* #param array $multipleModels
* #return array
*/
public static function createMultiple($modelClass, $multipleModels = [])
{
$model = new $modelClass;
$formName = $model->formName();
$post = Yii::$app->request->post($formName);
$models = [];
if (! empty($multipleModels)) {
$keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));
$multipleModels = array_combine($keys, $multipleModels);
}
if ($post && is_array($post)) {
foreach ($post as $i => $item) {
if (isset($item['id']) && !empty($item['id']) && isset($multipleModels[$item['id']])) {
$models[] = $multipleModels[$item['id']];
} else {
$models[] = new $modelClass;
}
}
}
unset($model, $formName, $post);
return $models;
In the years loop You use $n but input names have $i inside. So all Your inputs are initialized with [0] prefix. That's why on server side You have only the last record.
Just change [{$i}]id to [{$n}]id, [{$i}]year to [{$n}]year and so on
I'm trying to incorporate wbraganca dynamic form in yii2. But it's inserting data in only bills table(equivalent to the customer table) but not in productsales table(equivalent to address table). I'm not getting where the error is. There's no error in the console. After hitting the create button the page goes blank with a white screen. I can see data inserted in the bills table but not in productsales table.
_form.php in bills -
<?php
use yii\helpers\Html;
use yii\helpers\Url;
use kartik\form\ActiveForm;
use dosamigos\datepicker\DatePicker;
use yii\helpers\ArrayHelper;
use kartik\select2\Select2;
use yii\helpers\Json;
use yii\web\View;
use frontend\modules\invoice\models\Parties;
use frontend\modules\invoice\models\Productbatch;
use frontend\modules\invoice\models\Year;
use frontend\modules\invoice\models\Console;
use wbraganca\dynamicform\DynamicFormWidget;
use kartik\depdrop\DepDrop;
/* #var $this yii\web\View */
/* #var $model frontend\modules\invoice\models\Bills */
/* #var $form yii\widgets\ActiveForm */
?>
<div class="bills-form">
<?php $form = ActiveForm::begin([
'id' => 'dynamic-form',
'type' => ActiveForm::TYPE_HORIZONTAL,
'formConfig' => ['labelSpan' => 3, 'deviceSize' => ActiveForm::SIZE_SMALL]
]); ?>
<div class="row">
<div class="form-group">
<div class="col-xs-9 col-sm-9 col-lg-9">
<?= $form->field($model, 'bills_partyname')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Parties::find()->orderBy(['parties_partyname' => SORT_ASC,])->all(),'parties_partyname','partyDetails'),
'language' => 'en',
'options' => ['placeholder' => 'Select Party Name', 'id' => 'partyid'],
'pluginOptions' => [
'allowClear' => true
],
]); ?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($model, 'transport')->textInput(['maxlength' => true]) ?>
</div>
</div>
<div class="form-group">
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($model, 'bills_year')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Year::find()->orderBy(['yid' => SORT_DESC,])->all(),'year_year','year_year'),
'language' => 'en',
'options' => ['placeholder' => 'Select Year', 'id' => 'yearid'],
'pluginOptions' => [
'allowClear' => true
],
]); ?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($model, 'console')->widget(Select2::classname(), [
'data' => ArrayHelper::map(Console::find()->orderBy(['consoleid' => SORT_ASC,])->all(),'console','console'),
'language' => 'en',
'options' => ['placeholder' => 'Select Console','id' => 'consoleid'],
'pluginOptions' => [
'allowClear' => true
],
]); ?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($model, 'billno')->textInput(['maxlength' => true,'readOnly'=>true]) ?>
</div>
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($model, 'billdate')->widget(
DatePicker::className(), [
// inline too, not bad
'inline' => false,
// modify template for custom rendering
//'template' => '<div class="well well-sm" style="background-color: #fff; width:250px">{input}</div>',
'clientOptions' => [
'autoclose' => true,
'todayHighlight' => true,
'format' => 'yyyy-mm-dd'
]
]);?>
</div>
</div>
<?= $form->field($model, 'bills_ebillid')->textInput()->hiddenInput()->label(false) ?>
<?= $form->field($model, 'num')->textInput()->hiddenInput()->label(false) ?>
</div>
<div class="row">
<div class="panel panel-default">
<div class="panel-heading"><h4><i class="glyphicon glyphicon-envelope"></i> Products</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' => 20, // 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' => $modelsProductsales[0],
'formId' => 'dynamic-form',
'formFields' => [
//'itemid',
'productname',
//'batchno',
// 'expdate',
// 'mrp',
// 'rate',
// 'qty',
// 'free',
// 'total',
// 'discount',
],
]); ?>
<div class="container-items"><!-- widgetContainer -->
<?php foreach ($modelsProductsales as $i => $modelsProductsales): ?>
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<h3 class="panel-title pull-left">Products</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 (! $modelsProductsales->isNewRecord) {
echo Html::activeHiddenInput($modelsProductsales, "[{$i}]id");
}
?>
<div class="row-fluid">
<div class="form-group">
<div class="col-xs-3 col-sm-3 col-lg-3">
<?= $form->field($modelsProductsales, "[{$i}]productname")->label(false)->textInput(['maxlength' => true,'placeholder' => 'Productname']) ?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1 nopadding">
<?= $form->field($modelsProductsales, "[{$i}]batchno")->label(false)->textInput(['maxlength' => true,'placeholder' => 'Batchno']) ?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1 nopadding" >
<?= $form->field($modelsProductsales, "[{$i}]expdate")->label(false)->textInput(['maxlength' => true,'placeholder' => 'ExpDate']) ?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1 nopadding">
<?= $form->field($modelsProductsales, "[{$i}]mrp")->label(false)->textInput(['maxlength' => true,'placeholder' => 'MRP']) ?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1 nopadding">
<?= $form->field($modelsProductsales, "[{$i}]rate")->label(false)->textInput(['maxlength' => true,'placeholder' => 'Rate']) ?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1 nopadding">
<?= $form->field($modelsProductsales, "[{$i}]qty")->label(false)->textInput(['maxlength' => true,'placeholder' => 'Qty']) ?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1 nopadding">
<?= $form->field($modelsProductsales, "[{$i}]free")->label(false)->textInput(['maxlength' => true,'placeholder' => 'Free']) ?>
</div>
<div class="col-xs-1 col-sm-1 col-lg-1 nopadding">
<?= $form->field($modelsProductsales, "[{$i}]discount")->label(false)->textInput(['maxlength' => true,'placeholder' => 'Discount']) ?>
</div>
</div>
<?= $form->field($modelsProductsales, "[{$i}]itemid")->textInput(['maxlength' => true]) ?>
<?= $form->field($modelsProductsales, "[{$i}]total")->textInput(['maxlength' => true]) ?>
</div><!-- .row -->
</div>
</div><!-- item panel default -->
<?php endforeach; ?>
</div><!-- container item -->
<?php DynamicFormWidget::end(); ?>
</div><!-- panel body -->
</div><!-- panel default -->
</div><!-- outer row -->
<?= $form->field($model, 'billamount')->textInput() ?>
<?= $form->field($model, 'overdue')->textInput() ?>
<?= $form->field($model, 'cst')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'wbst')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'caseno')->textInput() ?>
<?= $form->field($model, 'amount')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'discount')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'tot')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'surcharge')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'total')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'tax')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'mrpvalue')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'cstpercent')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'wbstpercent')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'surpercent')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'totpercent')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'transport')->textInput(['maxlength' => true]) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
/* start getting the transportdata */
$script = <<< JS
$('#partyid').change(function(){
var partyid = $(this).val();
$.get('index.php?r=invoice/bills/get-for-party',{ partyid : partyid }, function(data){
//alert(data);
var data = $.parseJSON(data);
$('#bills-transport').attr('value',data.transport);
});
});
JS;
$this->registerJs($script);
/* end getting the transportdata */
?>
<?php
/* start getting the ebilid */
$script = <<<EOD
$(window).load(function(){
$.get('index.php?r=invoice/bills/get-for-ebillid',{ ebillid : 1 }, function(data){
//alert(data);
var data = $.parseJSON(data);
$('#bills-bills_ebillid').attr('value',data.ebillid);
}
);
});
EOD;
$this->registerJs($script);
/*end getting the ebillid */
?>
<?php
/* start getting the num */
$script = <<< JS
$(function(){
$('#yearid').change(function(){
getNum();
});
$('#consoleid').change(function(){
getNum();
});
var yearid = $(this).val();
var consoleid = $(this).val();
var getNum = function(){
var yearid = String($('#yearid').val());
var consoleid = String($('#consoleid').val());
$.get('index.php?r=invoice/bills/get-for-num',{ yearid : yearid, consoleid : consoleid }, function(data){
//alert(data);
var data = $.parseJSON(data);
var getNum = data;
$('#bills-num').val(getNum["num"]);
});
} ;
});
JS;
$this->registerJs($script);
/* end getting the num */
?>
<?php
/* start getting the billno */
$script = <<< JS
$(function(){
$('#yearid').change(function(){
getBillno();
});
$('#consoleid').change(function(){
getBillno();
});
var yearid = $(this).val();
var consoleid = $(this).val();
var getBillno = function(){
var yearid = String($('#yearid').val());
var consoleid = String($('#consoleid').val());
$.get('index.php?r=invoice/bills/get-for-billno',{ yearid : yearid, consoleid : consoleid }, function(data){
//alert(data);
var data = $.parseJSON(data);
var getBillno = data;
$('#bills-billno').val(getBillno["billno"]);
});
} ;
});
JS;
$this->registerJs($script);
/* end getting the billno */
?>
BillsController
<?php
namespace frontend\modules\invoice\controllers;
use Yii;
use frontend\modules\invoice\models\Bills;
use frontend\modules\invoice\models\BillsSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use frontend\modules\invoice\models\Parties;
use frontend\modules\invoice\models\Productsales;
use frontend\modules\invoice\models\Productbatch;
use frontend\modules\invoice\models\Model;
use yii\helpers\Json;
/**
* BillsController implements the CRUD actions for Bills model.
*/
class BillsController extends Controller
{
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
];
}
/**
* Lists all Bills models.
* #return mixed
*/
public function actionIndex()
{
$searchModel = new BillsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
/**
* Displays a single Bills model.
* #param string $id
* #return mixed
*/
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
/**
* Creates a new Bills model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionCreate()
{
$model = new Bills();
$modelsProductsales = [new Productsales];
if ($model->load(Yii::$app->request->post()) && $model->save()) {
$modelsProductsales = Model::createMultiple(Productsales::classname());
Model::loadMultiple($modelsProductsales, Yii::$app->request->post());
// validate all models
$valid = $model->validate();
$valid = Model::validateMultiple($modelsProductsales) && $valid;
if ($valid) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
foreach ($modelsProductsales as $modelProductsales) {
$modelProductsales->productsales_ebillid = $model->bills_ebillid;
$modelProductsales->year = $model->bills_year;
$modelProductsales->console = $model->console;
$modelProductsales->billno = $model->billno;
$modelProductsales->billdate = $model->billdate;
$modelProductsales->productsales_partyname = $model->bills_partyname;
if (! ($flag = $modelProductsales->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->billid]);
else {
return $this->render('create', [
'model' => $model,
'modelsProductsales' => (empty($modelsProductsales)) ? [new Productsales] : $modelsProductsales
]);
}
}
/**
* Updates an existing Bills model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param string $id
* #return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->billid]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing Bills model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* #param string $id
* #return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
public function actionGetForParty($partyid)
{
$party = Parties::find()->where(['parties_partyname'=>$partyid])->asArray()->one();
//$bottle -> select(['productnames.productnames_productname','productnames.bottletype','bottlename.unitprice'])->from('Productnames')->leftJoin('bottlename','productnames.bottletype = bottlename.bottlename')->where(['productnames_productname'=>$catid])->limit(1);
echo Json::encode($party);
}
public function actionGetForEbillid($ebillid)
{
$ebillidvar = Bills::find()->select('(max(bills_ebillid) + 1) as ebillid')->asArray()->one();
echo Json::encode($ebillidvar);
}
public function actionGetForNum($yearid , $consoleid)
{
$num = Bills::find()->select('(max(num) + 1) as num')->where(['bills_year'=>$yearid])->andWhere(['console'=>$consoleid])->asArray()->one();
echo Json::encode($num);
}
public function actionGetForItemid($productid , $batchid)
{
$item = Productbatch::find()->select('max(itemid) as itemid')->where(['productname'=>$productid])->andWhere(['batchno'=>$batchid])->asArray()->one();
echo Json::encode($item);
}
public function actionGetForBillno($yearid , $consoleid)
{
if($consoleid == 'GM1' || $consoleid == 'GM2'){
$num = Bills::find()->select(['concat("GM/",(max(num) + 1)) as billno'])->where(['bills_year'=>$yearid])->andWhere(['console'=>$consoleid])->asArray()->one();
echo Json::encode($num);
}elseif($consoleid == 'SM1' || $consoleid == 'SM2'){
$num = Bills::find()->select(['concat("SM/",(max(num) + 1)) as billno'])->where(['bills_year'=>$yearid])->andWhere(['console'=>$consoleid])->asArray()->one();
echo Json::encode($num);
}elseif($consoleid == 'CN'){
$num = Bills::find()->select(['concat("CM/",(max(num) + 1)) as billno'])->where(['bills_year'=>$yearid])->andWhere(['console'=>$consoleid])->asArray()->one();
echo Json::encode($num);
}
}
public function actionSubcat() {
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$cat_id = $parents[0];
$out = Productbatch::getBatchNo($cat_id);
echo Json::encode($out);
// the getSubCatList function will query the database based on the
// cat_id and return an array like below:
// [
// ['id'=>'<sub-cat-id-1>', 'name'=>'<sub-cat-name1>'],
// ['id'=>'<sub-cat_id_2>', 'name'=>'<sub-cat-name2>']
// ]
//echo Json::encode(['output'=>$out, 'selected'=>'']);
return;
}
}
echo Json::encode(['output'=>'', 'selected'=>'']);
}
/**
* Finds the Bills model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param string $id
* #return Bills the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Bills::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
Create.php
<?php
use yii\helpers\Html;
/* #var $this yii\web\View */
/* #var $model frontend\modules\invoice\models\Bills */
$this->title = 'Create Bills';
$this->params['breadcrumbs'][] = ['label' => 'Bills', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="bills-create">
<h1><?= Html::encode($this->title) ?></h1>
<?= $this->render('_form', [
'model' => $model,
'modelsProductsales' => $modelsProductsales,
]) ?>
</div>
Model.php
<?php
namespace frontend\modules\invoice\models;
use Yii;
use yii\helpers\ArrayHelper;
class Model extends \yii\base\Model
{
/**
* Creates and populates a set of models.
*
* #param string $modelClass
* #param array $multipleModels
* #return array
*/
public static function createMultiple($modelClass, $multipleModels = [])
{
$model = new $modelClass;
$formName = $model->formName();
$post = Yii::$app->request->post($formName);
$models = [];
if (! empty($multipleModels)) {
$keys = array_keys(ArrayHelper::map($multipleModels, 'id', 'id'));
$multipleModels = array_combine($keys, $multipleModels);
}
if ($post && is_array($post)) {
foreach ($post as $i => $item) {
if (isset($item['id']) && !empty($item['id']) && isset($multipleModels[$item['id']])) {
$models[] = $multipleModels[$item['id']];
} else {
$models[] = new $modelClass;
}
}
}
unset($model, $formName, $post);
return $models;
}
}
I am getting same index( 0 ) for all new items rather than incremented index. I dont know what and where is wrong with my code. i am working on this by referring to this demo Nested Dynamic Form - Yii2. sorry for my bad english.
My Controller
This is my controller.
public function actionUpdateperkara($id)
{
$model = $this->findModel($id);
$modelsPerkaraSatu = $model->tblMinitperkaras;
$modelsPerkaraDua = [];
$oldPerkaraDuas = [];
if (!empty($modelsPerkaraSatu)) {
foreach ($modelsPerkaraSatu as $indexPerkaraSatu => $modelPerkaraSatu) {
$perkaraduas = $modelPerkaraSatu->tblMinitperkara2s;
$modelsPerkaraDua[$indexPerkaraSatu] = $perkaraduas;
$oldPerkaraDuas = ArrayHelper::merge(ArrayHelper::index($perkaraduas, 'per_id'), $oldPerkaraDuas);
}
}
if ($model->load(Yii::$app->request->post())) {
// reset
$modelsPerkaraDua = [];
$oldPerkaraSatuIDs = ArrayHelper::map($modelsPerkaraSatu, 'perkara_id', 'perkara_id');
$modelsPerkaraSatu = ModelPerkara::createMultiple(TblMinitperkara::classname(), $modelsPerkaraSatu);
ModelPerkara::loadMultiple($modelsPerkaraSatu, Yii::$app->request->post());
$deletedPerkaraSatuIDs = array_diff($oldPerkaraSatuIDs, array_filter(ArrayHelper::map($modelsPerkaraSatu, 'perkara_id', 'perkara_id')));
// validate model and tblMinitperkaras models
$valid = $model->validate();
$valid = ModelPerkara::validateMultiple($modelsPerkaraSatu) && $valid;
$perkaraDuasIDs = [];
if (isset($_POST['TblMinitperkara2'][0][0])) {
foreach ($_POST['TblMinitperkara2'] as $indexPerkaraSatu => $perkaraduas) {
$perkaraDuasIDs = ArrayHelper::merge($perkaraDuasIDs, array_filter(ArrayHelper::getColumn($perkaraduas, 'per_id')));
foreach ($perkaraduas as $indexPerkaraDua => $perkaradua) {
$data['TblMinitperkara2'] = $perkaradua;
$modelPerkaraDua = (isset($perkaradua['per_id']) && isset($oldPerkaraDuas[$perkaradua['per_id']])) ? $oldPerkaraDuas[$perkaradua['per_id']] : new TblMinitperkara2;
$modelPerkaraDua->load($data);
$modelsPerkaraDua[$indexPerkaraSatu][$indexPerkaraDua] = $modelPerkaraDua;
$valid = $modelPerkaraDua->validate();
}
}
}
$oldPerkaraDuasIDs = ArrayHelper::getColumn($oldPerkaraDuas, 'per_id');
$deletedPerkaraDuasIDs = array_diff($oldPerkaraDuasIDs, $perkaraDuasIDs);
if ($valid) {
$transaction = Yii::$app->db->beginTransaction();
try {
if ($flag = $model->save(false)) {
if (! empty($deletedPerkaraDuasIDs)) {
TblMinitperkara2::deleteAll(['per_id' => $deletedPerkaraDuasIDs]);
}
if (! empty($deletedPerkaraSatuIDs)) {
TblMinitperkara::deleteAll(['perkara_id' => $deletedPerkaraSatuIDs]);
}
foreach ($modelsPerkaraSatu as $indexPerkaraSatu => $modelPerkaraSatu) {
if ($flag === false) {
break;
}
$modelPerkaraSatu->butir_id = $model->butir_id;
if (!($flag = $modelPerkaraSatu->save(false))) {
break;
}
if (isset($modelsPerkaraDua[$indexPerkaraSatu]) && is_array($modelsPerkaraDua[$indexPerkaraSatu])) {
foreach ($modelsPerkaraDua[$indexPerkaraSatu] as $indexPerkaraDua => $modelPerkaraDua) {
$modelPerkaraDua->perkara_id = $modelPerkaraSatu->perkara_id;
if (!($flag = $modelPerkaraDua->save(false))) {
break;
}
}
}
}
}
if ($flag) {
$transaction->commit();
return $this->redirect(['view', 'id' => $model->butir_id]);
}
else {
$transaction->rollBack();
}
}
catch (Exception $e) {
$transaction->rollBack();
}
}
}
return $this->render('_form_perkara', [
'model' => $model,
'modelsPerkaraSatu' => (empty($modelsPerkaraSatu)) ? [new TblMinitperkara] : $modelsPerkaraSatu,
'modelsPerkaraDua' => (empty($modelsPerkaraDua)) ? [[new TblMinitperkara2]] : $modelsPerkaraDua
]);
}
_form_perkara
This is my form.
<?php
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;
use yii\widgets\ActiveForm;
use wbraganca\dynamicform\DynamicFormWidget;
use yii\jui\JuiAsset;
use yii\web\Response;
use yii\web\JsExpression;
use kartik\file\FileInput;
use kartik\date\DatePicker;
use kartik\time\TimePicker;
/* #var $this yii\web\View */
/* #var $model frontend\models\TblMinitbutiran */
/* #var $form yii\widgets\ActiveForm */
$this->title = 'Minit Mesyuarat : ' . $model->butir_id;
$this->params['breadcrumbs'][] = ['label' => 'Senarai Minit Mesyuarat', 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => 'Minit Mesyuarat : ' . $model->butir_id, 'url' => ['view', 'id' => $model->butir_id]];
$this->params['breadcrumbs'][] = 'Butiran Perkara';
?>
<div>
<?php $form = ActiveForm::begin(['id' => 'dynamic-form']); ?>
<div class="panel panel-primary">
<div class="panel-heading"><b>Butiran Mesyuarat</b></div>
<div class="panel-body">
<div class="col-sm-3 ">
<?= $form->field($model, 'butir_bil')->textInput(['maxlength' => true]) ?>
</div>
<div class="col-sm-4 ">
<?= $form->field($model, 'butir_tarikh')->widget(DatePicker::classname(), [
'options' => ['placeholder' => 'pilih tarikh mesyuarat'],
'pluginOptions' => [
'format' => 'yyyy-mm-dd',
'endDate' => '+0d',
'autoclose'=>true
]
]); ?>
<?= $form->field($model, 'butir_masa')->widget(TimePicker::classname(), [
'pluginOptions' => [
'showMeridian'=>false
]
]); ?>
</div>
<div class="col-sm-5">
<?= $form->field($model, 'butir_tempat')->textarea(['rows' => 4]) ?>
</div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading"><b>Perkara</b></div>
<div class="panel-body">
<?php DynamicFormWidget::begin([
'widgetContainer' => 'dynamicform_wrapper',
'widgetBody' => '.container-items',
'widgetItem' => '.house-item',
'min' => 1,
'insertButton' => '.add-house',
'deleteButton' => '.remove-house',
'model' => $modelsPerkaraSatu[0],
'formId' => 'dynamic-form',
'formFields' => [
'perkara_bil',
'perkara_perkara',
],
]); ?>
<div>
<div>
<div style="overflow:hidden; height:30px;">
<div class="col-md-1 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:left"><b>BIL</b></div>
<div class="col-md-9 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:left"><b>PERKARA</b></div>
<div class="col-md-2 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:left"><b>TINDAKAN / MAKLUMAN</b></div>
</div>
</div>
<div class="container-items">
<?php foreach ($modelsPerkaraSatu as $indexPerkaraSatu => $modelPerkaraSatu): ?>
<div class="house-item">
<div class="col-md-1 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:center">
<?php
// necessary for update action.
if (! $modelPerkaraSatu->isNewRecord) {
echo Html::activeHiddenInput($modelPerkaraSatu, "[{$indexPerkaraSatu}]perkara_id");
}
?>
<?= $form->field($modelPerkaraSatu, "[{$indexPerkaraSatu}]perkara_bil")->label(false)->textInput(['maxlength' => true]) ?>
</div>
<div class="col-md-9 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:center">
<?= $form->field($modelPerkaraSatu, "[{$indexPerkaraSatu}]perkara_perkara")->label(false)->textInput(['maxlength' => true]) ?>
</div>
<div class="col-md-2 alert alert-info" role="alert" style="padding:5px; height:50px; text-align:center">
<button type="button" class="add-house btn btn-success btn-xs"><span class="glyphicon glyphicon-plus"></span></button>
<button type="button" class="remove-house btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus"></span></button>
</div>
<?= $this->render('_form_perkara2', [
'form' => $form,
'indexPerkaraSatu' => $indexPerkaraSatu,
'modelsPerkaraDua' => $modelsPerkaraDua[$indexPerkaraSatu],
]) ?>
</div>
<?php endforeach; ?>
</div>
</div>
<?php DynamicFormWidget::end(); ?>
</div>
</div>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Hantar' : 'Hantar', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<script type="text/javascript">
$(".dynamicform_wrapper").on("beforeInsert", function(e, item) {
console.log("beforeInsert");
});
$(".dynamicform_wrapper").on("afterInsert", function(e, item) {
console.log("afterInsert");
});
$(".dynamicform_wrapper").on("beforeDelete", function(e, item) {
if (! confirm("Are you sure you want to delete this item?")) {
return false;
}
return true;
});
$(".dynamicform_wrapper").on("afterDelete", function(e) {
console.log("Deleted item!");
});
$(".dynamicform_wrapper").on("limitReached", function(e, item) {
alert("Limit reached");
});
</script>
_form_perkara2
<?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-room',
'deleteButton' => '.remove-room',
'model' => $modelsPerkaraDua[0],
'formId' => 'dynamic-form',
'formFields' => [
'per_no',
'per_butiran',
'per_maklumat'
],
]); ?>
<div class="container-rooms" style="align:center">
<?php foreach ($modelsPerkaraDua as $indexPerkaraDua => $modelPerkaraDua): ?>
<div class="room-item">
<div class="col-md-1 alert alert-danger" role="alert" style="padding:5px; height:50px; text-align:center">
<button type="button" class="add-room btn btn-primary btn-xs"><span class="glyphicon glyphicon-plus"></span></button>
<button type="button" class="remove-room btn btn-warning btn-xs"><span class="glyphicon glyphicon-minus"></span></button>
</div>
<div class="col-md-1 alert alert-danger" role="alert" style="padding:5px; height:50px; text-align:center">
<?php
// necessary for update action.
if (! $modelPerkaraDua->isNewRecord) {
echo Html::activeHiddenInput($modelPerkaraDua, "[{$indexPerkaraSatu}][{$indexPerkaraDua}]per_id");
}
?>
<?= $form->field($modelPerkaraDua, "[{$indexPerkaraSatu}][{$indexPerkaraDua}]per_no")->label(false)->textInput(['maxlength' => true]) ?>
</div>
<div class="col-md-8 alert alert-danger" role="alert" style="padding:5px; height:50px; text-align:center">
<?= $form->field($modelPerkaraDua, "[{$indexPerkaraSatu}][{$indexPerkaraDua}]per_butiran")->label(false)->textInput(['maxlength' => true]) ?>
</div>
<div class="col-md-2 alert alert-danger" role="alert" style="padding:5px; height:50px; text-align:center">
<?= $form->field($modelPerkaraDua, "[{$indexPerkaraSatu}][{$indexPerkaraDua}]per_maklumat")->label(false)->textInput(['maxlength' => true]) ?>
</div>
</div>
<?php endforeach; ?>
</div>
<?php DynamicFormWidget::end(); ?>
ModelPerkara class
<?php
namespace frontend\models;
use Yii;
use yii\helpers\ArrayHelper;
class ModelPerkara extends \yii\base\Model
{
/**
* Creates and populates a set of models.
*
* #param string $modelClass
* #param array $multipleModels
* #return array
*/
public static function createMultiple($modelClass, $multipleModels = [])
{
$model = new $modelClass;
$formName = $model->formName();
$post = Yii::$app->request->post($formName);
$models = [];
if (! empty($multipleModels)) {
$keys = array_keys(ArrayHelper::map($multipleModels, 'perkara_id', 'perkara_id'));
$multipleModels = array_combine($keys, $multipleModels);
}
if ($post && is_array($post)) {
foreach ($post as $indexPerkaraSatu => $item) {
if (isset($item['perkara_id']) && !empty($item['perkara_id']) && isset($multipleModels[$item['perkara_id']])) {
$models[] = $multipleModels[$item['perkara_id']];
} else {
$models[] = new $modelClass;
}
}
}
unset($model, $formName, $post);
return $models;
}
}
Screenshot of inspector
input id in second div of "house-item" is same with the first one. This show that the index is not increments
You need to add javascript events in your view file.
$js = '
jQuery(".dynamicform_wrapper").on("afterInsert", function(e, item) {
jQuery(".dynamicform_wrapper .panel-title-address").each(function(index) {
jQuery(this).html("Address: " + (index + 1))
});
});
jQuery(".dynamicform_wrapper").on("afterDelete", function(e) {
jQuery(".dynamicform_wrapper .panel-title-address").each(function(index) {
jQuery(this).html("Address: " + (index + 1))
});
});
';
$this->registerJs($js);