dev-master
9999999-devIt is widget to yii2 framework to clone form elements in a nested manner, maintaining accessibility.
BSD-3-Clause
The Requires
extension yii2 widget copy dom element yii2-dynamicform yii2 dynamic form jcabanillas
It is widget to yii2 framework to clone form elements in a nested manner, maintaining accessibility.
It is widget to yii2 framework to clone form elements in a nested manner, maintaining accessibility. , (*2)
The preferred way to install this extension is through composer., (*3)
Either run, (*4)
php composer.phar require --prefer-dist jcabanillas/yii2-dynamicform "*"
or add, (*5)
"jcabanillas/yii2-dynamicform": "*"
to the require section of your composer.json
file., (*6)
, (*7)
'dynamic-form']); ?>= $form->field($modelCustomer, 'first_name')->textInput(['maxlength' => true]) ?>= $form->field($modelCustomer, 'last_name')->textInput(['maxlength' => true]) ?>Addresses
'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_] 'widgetBody' => '.container-items', // required: css class selector 'widgetItem' => '.item', // required: css class 'limit' => 4, // 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' => $modelsAddress[0], 'formId' => 'dynamic-form', 'formFields' => [ 'full_name', 'address_line1', 'address_line2', 'city', 'state', 'postal_code', ], ]); ?>$modelAddress): ?>Address
isNewRecord) { echo Html::activeHiddenInput($modelAddress, "[{$i}]id"); } ?> = $form->field($modelAddress, "[{$i}]full_name")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]address_line1")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]address_line2")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]city")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]state")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]postal_code")->textInput(['maxlength' => true]) ?>= Html::submitButton($modelAddress->isNewRecord ? 'Create' : 'Update', ['class' => 'btn btn-primary']) ?>
$(".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"); });
load(Yii::$app->request->post())) { $modelsAddress = Model::createMultiple(Address::classname()); Model::loadMultiple($modelsAddress, Yii::$app->request->post()); // ajax validation if (Yii::$app->request->isAjax) { Yii::$app->response->format = Response::FORMAT_JSON; return ArrayHelper::merge( ActiveForm::validateMultiple($modelsAddress), ActiveForm::validate($modelCustomer) ); } // validate all models $valid = $modelCustomer->validate(); $valid = Model::validateMultiple($modelsAddress) && $valid; if ($valid) { $transaction = \Yii::$app->db->beginTransaction(); try { if ($flag = $modelCustomer->save(false)) { foreach ($modelsAddress as $modelAddress) { $modelAddress->customer_id = $modelCustomer->id; if (! ($flag = $modelAddress->save(false))) { $transaction->rollBack(); break; } } } if ($flag) { $transaction->commit(); return $this->redirect(['view', 'id' => $modelCustomer->id]); } } catch (Exception $e) { $transaction->rollBack(); } } } return $this->render('create', [ 'modelCustomer' => $modelCustomer, 'modelsAddress' => (empty($modelsAddress)) ? [new Address] : $modelsAddress ]); } /** * Updates an existing Customer model. * If update is successful, the browser will be redirected to the 'view' page. * @param integer $id * @return mixed */ public function actionUpdate($id) { $modelCustomer = $this->findModel($id); $modelsAddress = $modelCustomer->addresses; if ($modelCustomer->load(Yii::$app->request->post())) { $oldIDs = ArrayHelper::map($modelsAddress, 'id', 'id'); $modelsAddress = Model::createMultiple(Address::classname(), $modelsAddress); Model::loadMultiple($modelsAddress, Yii::$app->request->post()); $deletedIDs = array_diff($oldIDs, array_filter(ArrayHelper::map($modelsAddress, 'id', 'id'))); // ajax validation if (Yii::$app->request->isAjax) { Yii::$app->response->format = Response::FORMAT_JSON; return ArrayHelper::merge( ActiveForm::validateMultiple($modelsAddress), ActiveForm::validate($modelCustomer) ); } // validate all models $valid = $modelCustomer->validate(); $valid = Model::validateMultiple($modelsAddress) && $valid; if ($valid) { $transaction = \Yii::$app->db->beginTransaction(); try { if ($flag = $modelCustomer->save(false)) { if (! empty($deletedIDs)) { Address::deleteAll(['id' => $deletedIDs]); } foreach ($modelsAddress as $modelAddress) { $modelAddress->customer_id = $modelCustomer->id; if (! ($flag = $modelAddress->save(false))) { $transaction->rollBack(); break; } } } if ($flag) { $transaction->commit(); return $this->redirect(['view', 'id' => $modelCustomer->id]); } } catch (Exception $e) { $transaction->rollBack(); } } } return $this->render('update', [ 'modelCustomer' => $modelCustomer, 'modelsAddress' => (empty($modelsAddress)) ? [new Address] : $modelsAddress ]); } ... } ``` ### Model Class ```php 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; } } ``` ### To zero or more elements (use the following code in your view file) ```php'dynamic-form']); ?>'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_] 'widgetBody' => '.container-items', // required: css class selector 'widgetItem' => '.item', // required: css class 'limit' => 4, // the maximum times, an element can be added (default 999) 'min' => 0, // 0 or 1 (default 1) 'insertButton' => '.add-item', // css class 'deleteButton' => '.remove-item', // css class 'model' => $modelsAddress[0], 'formId' => 'dynamic-form', 'formFields' => [ 'full_name', 'address_line1', 'address_line2', 'city', 'state', 'postal_code', ], ]); ?>= $form->field($modelCustomer, 'first_name')->textInput(['maxlength' => true]) ?>= $form->field($modelCustomer, 'last_name')->textInput(['maxlength' => true]) ?>Addresses
$modelAddress): ?>Address
isNewRecord) { echo Html::activeHiddenInput($modelAddress, "[{$i}]id"); } ?> = $form->field($modelAddress, "[{$i}]full_name")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]address_line1")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]address_line2")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]city")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]state")->textInput(['maxlength' => true]) ?>= $form->field($modelAddress, "[{$i}]postal_code")->textInput(['maxlength' => true]) ?>= Html::submitButton($modelAddress->isNewRecord ? 'Create' : 'Update', ['class' => 'btn btn-primary']) ?>
It is widget to yii2 framework to clone form elements in a nested manner, maintaining accessibility.
BSD-3-Clause
extension yii2 widget copy dom element yii2-dynamicform yii2 dynamic form jcabanillas