diff --git a/CHANGELOG.md b/CHANGELOG.md index e931c40..df97c69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,44 +3,45 @@ yii2-dynamicform change Log dev-master ---------- -- enh #24: Added support for "jquery.inputmask". It only works with Yii 2.0.4 or higher. -- enh: Remove "error/success" class css template to be cloned. -- bug: Fixes for: checkbox(), checkboxList(), radio() and radioList() +- Enh #25: Added enhancements to better support for nested widgets. +- Enh #24: Added support for "jquery.inputmask". It only works with Yii 2.0.4 or higher. +- Enh: Remove "error/success" class css template to be cloned. +- Bug: Fixes for: checkbox(), checkboxList(), radio() and radioList() version 2.0.2 ------------- **Date:** 25-Fev-2015 -- bug #22: Correct reset attributes (id, name) when we have more than two nested widgets +- Bug #22: Correct reset attributes (id, name) when we have more than two nested widgets version 2.0.1 ------------- **Date:** 23-Fev-2015 -- bug: Fixed error for the use of multiple nested widgets with zero initial elements +- Bug: Fixed error for the use of multiple nested widgets with zero initial elements version 2.0.0 ------------- **Date:** 22-Fev-2015 -- enh #20: Added trigger 'beforeDelete' -- bug #19: Fixes checkboxes on new items -- enh #15: Added support for multiple nested widgets +- Enh #20: Added trigger 'beforeDelete' +- Bug #19: Fixes checkboxes on new items +- Enh #15: Added support for multiple nested widgets version 1.1.0 ------------- **Date:** 16-Dez-2014 -- bug #7: Added support for "kartik-v/yii2-widget-depdrop" for working with type DepDrop::TYPE_SELECT2 -- bug #8: Fixes to support the latest version of kartik-v widgets -- bug: Fixed client validation -- bug #6: Fixed settings for datepicker -- enh: Added support for "kartik-v/yii2-widget-depdrop" -- enh: Added support for "kartik-v/yii2-widget-select2" -- bug: Fixed html name attribute for "kartik-v/yii2-widget-colorinput" -- enh: Added support for "kartik-v/yii2-widget-timepicker" -- enh: Added support for "kartik-v/yii2-widget-colorinput" +- Bug #7: Added support for "kartik-v/yii2-widget-depdrop" for working with type DepDrop::TYPE_SELECT2 +- Bug #8: Fixes to support the latest version of kartik-v widgets +- Bug: Fixed client validation +- Bug #6: Fixed settings for datepicker +- Enh: Added support for "kartik-v/yii2-widget-depdrop" +- Enh: Added support for "kartik-v/yii2-widget-select2" +- Bug: Fixed html name attribute for "kartik-v/yii2-widget-colorinput" +- Enh: Added support for "kartik-v/yii2-widget-timepicker" +- Enh: Added support for "kartik-v/yii2-widget-colorinput" version 1.0.0 diff --git a/README.md b/README.md index 6b51fe2..0353cd1 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,6 @@ yii2-dynamicform [![Latest Version](https://img.shields.io/github/release/wbraganca/yii2-dynamicform.svg?style=flat-square)](https://github.com/wbraganca/yii2-dynamicform/releases) [![Software License](http://img.shields.io/badge/license-BSD3-brightgreen.svg?style=flat-square)](LICENSE.md) -[![Build Status](https://img.shields.io/travis/wbraganca/yii2-dynamicform/master.svg?style=flat-square)](https://travis-ci.org/wbraganca/yii2-dynamicform) -[![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/wbraganca/yii2-dynamicform.svg?style=flat-square)](https://scrutinizer-ci.com/g/wbraganca/yii2-dynamicform/code-structure) -[![Quality Score](https://img.shields.io/scrutinizer/g/wbraganca/yii2-dynamicform.svg?style=flat-square)](https://scrutinizer-ci.com/g/wbraganca/yii2-dynamicform) [![Total Downloads](https://img.shields.io/packagist/dt/wbraganca/yii2-dynamicform.svg?style=flat-square)](https://packagist.org/packages/wbraganca/yii2-dynamicform) @@ -32,10 +29,19 @@ or add to the require section of your `composer.json` file. +Demos +----- + +* [Demo 1](http://wbraganca.com/yii2extensions/dynamicform-demo1/) - (Address Book). +* [Demo 2](http://wbraganca.com/yii2extensions/dynamicform-demo2/) - (File Upload). +* [Demo 3](http://wbraganca.com/yii2extensions/dynamicform-demo3/) - (Nested Dynamic Form). + + Usage ----------- +----- + ###Hypothetical Scenario -![Database](http://wbraganca.com/img/yii2--db.png) +![Database](http://wbraganca.com/img/yii2-dynamicform/sample.jpg) ###The View diff --git a/src/DynamicFormWidget.php b/src/DynamicFormWidget.php index 3f56a71..9cf7d2f 100644 --- a/src/DynamicFormWidget.php +++ b/src/DynamicFormWidget.php @@ -7,6 +7,7 @@ namespace wbraganca\dynamicform; +use Yii; use Symfony\Component\DomCrawler\Crawler; use Symfony\Component\CssSelector\CssSelector; use yii\helpers\Json; @@ -20,7 +21,7 @@ */ class DynamicFormWidget extends \yii\base\Widget { - const HASH_VAR_BASE_NAME = 'dynamicform_'; + const WIDGET_NAME = 'dynamicform'; /** * @var string */ @@ -74,18 +75,23 @@ class DynamicFormWidget extends \yii\base\Widget */ private $_insertPositions = ['bottom', 'top']; /** - * @var string the hashed global variable name storing the pluginOptions + * @var string the hashed global variable name storing the pluginOptions. */ private $_hashVar; + /** + * @var string the Json encoded options. + */ + private $_encodedOptions = ''; /** - * Initializes the widget + * Initializes the widget. * * @throws \yii\base\InvalidConfigException */ public function init() { parent::init(); + if (empty($this->widgetContainer) || (preg_match('/^\w{1,}$/', $this->widgetContainer) === 0)) { throw new InvalidConfigException('Invalid configuration to property "widgetContainer". Allowed only alphanumeric characters plus underline: [A-Za-z0-9_]'); @@ -108,11 +114,12 @@ public function init() if (empty($this->formFields) || !is_array($this->formFields)) { throw new InvalidConfigException("The 'formFields' property must be set."); } + $this->initOptions(); } /** - * Initializes the widget options + * Initializes the widget options. */ protected function initOptions() { @@ -138,22 +145,62 @@ protected function initOptions() ob_implicit_flush(false); } + /** + * Registers plugin options by storing it in a hashed javascript variable. + * + * @param View $view The View object + */ protected function registerOptions($view) { - $encOptions = Json::encode($this->_options); - $this->_hashVar = DynamicFormWidget::HASH_VAR_BASE_NAME . hash('crc32', $encOptions); - $view->registerJs("var {$this->_hashVar} = {$encOptions};\n", $view::POS_HEAD); + $view->registerJs("var {$this->_hashVar} = {$this->_encodedOptions};\n", $view::POS_HEAD); } /** - * Registers the needed assets + * Generates a hashed variable to store the options. */ - public function registerAssets() + protected function hashOptions() + { + $this->_encodedOptions = Json::encode($this->_options); + $this->_hashVar = self::WIDGET_NAME . '_' . hash('crc32', $this->_encodedOptions); + } + + /** + * Returns the hashed variable. + * + * @return string + */ + protected function getHashVarName() + { + if (isset(Yii::$app->params[self::WIDGET_NAME][$this->widgetContainer])) { + return Yii::$app->params[self::WIDGET_NAME][$this->widgetContainer]; + } + + return $this->_hashVar; + } + + /** + * Register the actual widget. + * + * @return boolean + */ + public function registerHashVarWidget() + { + if (!isset(Yii::$app->params[self::WIDGET_NAME][$this->widgetContainer])) { + Yii::$app->params[self::WIDGET_NAME][$this->widgetContainer] = $this->_hashVar; + return true; + } + + return false; + } + + /** + * Registers the needed assets. + * + * @param View $view The View object + */ + public function registerAssets($view) { - $view = $this->getView(); DynamicFormAsset::register($view); - $options = Json::encode($this->_options); - $this->registerOptions($view); // add a click handler for the clone button $js = 'jQuery("#' . $this->formId . '").on("click", "' . $this->insertButton . '", function(e) {'. "\n"; @@ -174,6 +221,9 @@ public function registerAssets() $view->registerJs($js, $view::POS_LOAD); } + /** + * @inheritdoc + */ public function run() { $content = ob_get_clean(); @@ -188,10 +238,24 @@ public function run() $content = $this->removeItems($content); } - $this->registerAssets(); + $this->hashOptions(); + $view = $this->getView(); + $widgetRegistered = $this->registerHashVarWidget(); + $this->_hashVar = $this->getHashVarName(); + + if ($widgetRegistered) { + $this->registerOptions($view); + $this->registerAssets($view); + } + echo Html::tag('div', $content, ['class' => $this->widgetContainer, 'data-dynamicform' => $this->_hashVar]); } + /** + * Clear HTML widgetBody. Required to work with zero or more items. + * + * @param string $content + */ private function removeItems($content) { $document = new \DOMDocument('1.0', \Yii::$app->charset); diff --git a/src/assets/yii2-dynamic-form.min.js b/src/assets/yii2-dynamic-form.min.js index d3065d5..2ac16ef 100644 --- a/src/assets/yii2-dynamic-form.min.js +++ b/src/assets/yii2-dynamic-form.min.js @@ -5,4 +5,4 @@ * * @author Wanderson Bragança */ -!function($){var pluginName="yiiDynamicForm",regexID=/^(.+?)([-\d-]{1,})(.+)$/i,regexName=/(^.+?)([\[\d{1,}\]]{1,})(\[.+\]$)/i;$.fn.yiiDynamicForm=function(e){return methods[e]?methods[e].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof e&&e?($.error("Method "+e+" does not exist on jQuery.yiiDynamicForm"),!1):methods.init.apply(this,arguments)};var events={beforeInsert:"beforeInsert",afterInsert:"afterInsert",beforeDelete:"beforeDelete",afterDelete:"afterDelete",limitReached:"limitReached"},methods={init:function(e){return this.each(function(){e.template=_parseTemplate(e)})},addItem:function(e,t,i){_addItem(e,t,i)},deleteItem:function(e,t,i){_deleteItem(e,t,i)},updateContainer:function(){var widgetOptions=eval($(this).attr("data-dynamicform"));_updateAttributes(widgetOptions),_restoreSpecialJs(widgetOptions),_fixFormValidaton(widgetOptions)}},_parseTemplate=function(widgetOptions){var $template=$(widgetOptions.template);$template.find("div[data-dynamicform]").each(function(){var widgetOptions=eval($(this).attr("data-dynamicform"));if($(widgetOptions.widgetItem).length>1){var item=$(this).find(widgetOptions.widgetItem).first()[0].outerHTML;$(this).find(widgetOptions.widgetBody).html(item)}}),$template.find("input, textarea, select").each(function(){if($(this).is(":checkbox")||$(this).is(":radio")){var e=$(this).is(":checkbox")?"checkbox":"radio",t=$(this).attr("name"),i=$template.find('input[type="hidden"][name="'+t+'"]').first(),a=$template.find('input[type="'+e+'"][name="'+t+'"]').length;i&&1===a&&($(this).val(1),i.val(0)),$(this).prop("checked",!1)}else $(this).val("")});var yiiActiveFormData=$("#"+widgetOptions.formId).yiiActiveForm("data");return $template.find("."+yiiActiveFormData.settings.errorCssClass).removeClass(yiiActiveFormData.settings.errorCssClass),$template.find("."+yiiActiveFormData.settings.successCssClass).removeClass(yiiActiveFormData.settings.successCssClass),$template},_getWidgetOptionsRoot=function(widgetOptions){return eval($(widgetOptions.widgetBody).parents("div[data-dynamicform]").last().attr("data-dynamicform"))},_getLevel=function(e){var t=e.parents("div[data-dynamicform]").length;return t=0>t?0:t},_count=function(e,t){return e.closest("."+t.widgetContainer).find(t.widgetItem).length},_createIdentifiers=function(e){return new Array(e+2).join("0").split("")},_addItem=function(e,t,i){var a=_count(i,e);a1){$elem.find("div[data-dynamicform]").each(function(){for(var currentWidgetOptions=eval($(this).attr("data-dynamicform")),level=_getLevel($(this)),identifiers=_createIdentifiers(level),numItems=$(this).find(currentWidgetOptions.widgetItem).length,i=1;numItems-1>=i;i++){var aux=identifiers;aux[level]=i,currentWidgetOptions.fields.forEach(function(e){var t=e.id.replace("{}",aux.join("-"));"undefined"!==$("#"+currentWidgetOptions.formId).yiiActiveForm("find",t)&&$("#"+currentWidgetOptions.formId).yiiActiveForm("remove",t)})}});var level=_getLevel($elem.closest("."+widgetOptions.widgetContainer)),widgetOptionsRoot=_getWidgetOptionsRoot(widgetOptions),identifiers=_createIdentifiers(level);identifiers[0]=$(widgetOptionsRoot.widgetItem).length-1,identifiers[level]=count-1,widgetOptions.fields.forEach(function(e){var t=e.id.replace("{}",identifiers.join("-"));"undefined"!==$("#"+widgetOptions.formId).yiiActiveForm("find",t)&&$("#"+widgetOptions.formId).yiiActiveForm("remove",t)})}},_deleteItem=function(e,t,i){var a=_count(i,e);if(a>e.min){$todelete=i.closest(e.widgetItem);var n=$("."+e.widgetContainer).triggerHandler(events.beforeDelete,$todelete);n!==!1&&(_removeValidations($todelete,e,a),$todelete.remove(),_updateAttributes(e),_restoreSpecialJs(e),_fixFormValidaton(e),$("."+e.widgetContainer).triggerHandler(events.afterDelete))}},_updateAttrID=function($elem,index){var widgetOptions=eval($elem.closest("div[data-dynamicform]").attr("data-dynamicform")),id=$elem.attr("id"),newID=id;if(void 0!==id){var matches=id.match(regexID);if(matches&&4===matches.length){matches[2]=matches[2].substring(1,matches[2].length-1);var identifiers=matches[2].split("-");if(identifiers[0]=index,identifiers.length>1){var widgetsOptions=[];$elem.parents("div[data-dynamicform]").each(function(i){widgetsOptions[i]=eval($(this).attr("data-dynamicform"))}),widgetsOptions=widgetsOptions.reverse();for(var i=identifiers.length-1;i>=1;i--)identifiers[i]=$elem.closest(widgetsOptions[i].widgetItem).index()}newID=matches[1]+"-"+identifiers.join("-")+"-"+matches[3],$elem.attr("id",newID)}else newID=id+index,$elem.attr("id",newID)}return id!==newID&&($elem.closest(widgetOptions.widgetItem).find(".field-"+id).each(function(){$(this).removeClass("field-"+id).addClass("field-"+newID)}),$elem.closest(widgetOptions.widgetItem).find("label[for='"+id+"']").attr("for",newID)),newID},_updateAttrName=function($elem,index){var name=$elem.attr("name");if(void 0!==name){var matches=name.match(regexName);if(matches&&4===matches.length){matches[2]=matches[2].replace(/\]\[/g,"-").replace(/\]|\[/g,"");var identifiers=matches[2].split("-");if(identifiers[0]=index,identifiers.length>1){var widgetsOptions=[];$elem.parents("div[data-dynamicform]").each(function(i){widgetsOptions[i]=eval($(this).attr("data-dynamicform"))}),widgetsOptions=widgetsOptions.reverse();for(var i=identifiers.length-1;i>=1;i--)identifiers[i]=$elem.closest(widgetsOptions[i].widgetItem).index()}name=matches[1]+"["+identifiers.join("][")+"]"+matches[3],$elem.attr("name",name)}}return name},_updateAttributes=function(e){var t=_getWidgetOptionsRoot(e);$(t.widgetItem).each(function(e){$(this);$(this).find("*").each(function(){_updateAttrID($(this),e),_updateAttrName($(this),e)})})},_fixFormValidatonInput=function(e,t,i,a){void 0!==t&&(t=$.extend(!0,{},t),t.id=i,t.container=".field-"+i,t.input="#"+i,t.name=a,t.value=$("#"+i).val(),t.status=0,"undefined"!==$("#"+e.formId).yiiActiveForm("find",i)&&$("#"+e.formId).yiiActiveForm("remove",i),$("#"+e.formId).yiiActiveForm("add",t))},_fixFormValidaton=function(widgetOptions){var widgetOptionsRoot=_getWidgetOptionsRoot(widgetOptions);$(widgetOptionsRoot.widgetBody).find("input, textarea, select").each(function(){var id=$(this).attr("id"),name=$(this).attr("name");if(void 0!==id&&void 0!==name){currentWidgetOptions=eval($(this).closest("div[data-dynamicform]").attr("data-dynamicform"));var matches=id.match(regexID);if(matches&&4===matches.length){matches[2]=matches[2].substring(1,matches[2].length-1);var level=_getLevel($(this)),identifiers=_createIdentifiers(level-1),baseID=matches[1]+"-"+identifiers.join("-")+"-"+matches[3],attribute=$("#"+currentWidgetOptions.formId).yiiActiveForm("find",baseID);_fixFormValidatonInput(currentWidgetOptions,attribute,id,name)}}})},_restoreSpecialJs=function(widgetOptions){var widgetOptionsRoot=_getWidgetOptionsRoot(widgetOptions),$hasInputmask=$(widgetOptionsRoot.widgetItem).find("[data-plugin-inputmask]");$hasInputmask.length>0&&$hasInputmask.each(function(){$(this).inputmask("remove"),$(this).inputmask(eval($(this).attr("data-plugin-inputmask")))});var $hasDatepicker=$(widgetOptionsRoot.widgetItem).find("[data-krajee-datepicker]");$hasDatepicker.length>0&&$hasDatepicker.each(function(){$(this).parent().removeData().datepicker("remove"),$(this).parent().datepicker(eval($(this).attr("data-krajee-datepicker")))});var $hasTimepicker=$(widgetOptionsRoot.widgetItem).find("[data-krajee-timepicker]");$hasTimepicker.length>0&&$hasTimepicker.each(function(){$(this).removeData().off(),$(this).parent().find(".bootstrap-timepicker-widget").remove(),$(this).unbind(),$(this).timepicker(eval($(this).attr("data-krajee-timepicker")))});var $hasMaskmoney=$(widgetOptionsRoot.widgetItem).find("[data-krajee-maskMoney]");$hasMaskmoney.length>0&&$hasMaskmoney.each(function(){$(this).parent().find("input").removeData().off();var id="#"+$(this).attr("id"),displayID=id+"-disp";$(displayID).maskMoney("destroy"),$(displayID).maskMoney(eval($(this).attr("data-krajee-maskMoney"))),$(displayID).maskMoney("mask",parseFloat($(id).val())),$(displayID).on("change",function(){var e=$(displayID).maskMoney("unmasked")[0];$(id).val(e),$(id).trigger("change")})});var $hasFileinput=$(widgetOptionsRoot.widgetItem).find("[data-krajee-fileinput]");$hasFileinput.length>0&&$hasFileinput.each(function(){$(this).fileinput(eval($(this).attr("data-krajee-fileinput")))});var $hasTouchSpin=$(widgetOptionsRoot.widgetItem).find("[data-krajee-TouchSpin]");$hasTouchSpin.length>0&&$hasTouchSpin.each(function(){$(this).TouchSpin("destroy"),$(this).TouchSpin(eval($(this).attr("data-krajee-TouchSpin")))});var $hasSpectrum=$(widgetOptionsRoot.widgetItem).find("[data-krajee-spectrum]");$hasSpectrum.length>0&&$hasSpectrum.each(function(){var id="#"+$(this).attr("id"),sourceID=id+"-source";$(sourceID).spectrum("destroy"),$(sourceID).unbind(),$(id).unbind();var configSpectrum=eval($(this).attr("data-krajee-spectrum"));configSpectrum.change=function(e){jQuery(id).val(e.toString())},$(sourceID).attr("name",$(sourceID).attr("id")),$(sourceID).spectrum(configSpectrum),$(sourceID).spectrum("set",jQuery(id).val()),$(id).on("change",function(){$(sourceID).spectrum("set",jQuery(id).val())})});var $hasDepdrop=$(widgetOptionsRoot.widgetItem).find("[data-krajee-depdrop]");$hasDepdrop.length>0&&$hasDepdrop.each(function(){$(this).removeData().off(),$(this).unbind();var configDepdrop=eval($(this).attr("data-krajee-depdrop")),inputID=$(this).attr("id"),matchID=inputID.match(regex);if(matchID&&4===matchID.length)for(index=0;index0&&$hasSelect2.each(function(){var id=$(this).attr("id"),configSelect2=eval($(this).attr("data-krajee-select2"));$(this).select2("destroy"),$.when($("#"+id).select2(configSelect2)).done(initSelect2Loading(id)),$("#"+id).on("select2-open",function(){initSelect2DropStyle(id)}),$(this).attr("data-krajee-depdrop")&&($(this).on("depdrop.beforeChange",function(e,i,v){var configDepdrop=eval($(this).attr("data-krajee-depdrop")),loadingText=configDepdrop.loadingText?configDepdrop.loadingText:"Loading ...";$("#"+id).select2("data",{text:loadingText})}),$(this).on("depdrop.change",function(e,t,i,a){$("#"+id).select2("val",$("#"+id).val())}))})}}(window.jQuery); +!function($){var pluginName="yiiDynamicForm",regexID=/^(.+?)([-\d-]{1,})(.+)$/i,regexName=/(^.+?)([\[\d{1,}\]]{1,})(\[.+\]$)/i;$.fn.yiiDynamicForm=function(e){return methods[e]?methods[e].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof e&&e?($.error("Method "+e+" does not exist on jQuery.yiiDynamicForm"),!1):methods.init.apply(this,arguments)};var events={beforeInsert:"beforeInsert",afterInsert:"afterInsert",beforeDelete:"beforeDelete",afterDelete:"afterDelete",limitReached:"limitReached"},methods={init:function(e){return this.each(function(){e.template=_parseTemplate(e)})},addItem:function(e,t,i){_addItem(e,t,i)},deleteItem:function(e,t,i){_deleteItem(e,t,i)},updateContainer:function(){var widgetOptions=eval($(this).attr("data-dynamicform"));_updateAttributes(widgetOptions),_restoreSpecialJs(widgetOptions),_fixFormValidaton(widgetOptions)}},_parseTemplate=function(widgetOptions){var $template=$(widgetOptions.template);$template.find("div[data-dynamicform]").each(function(){var widgetOptions=eval($(this).attr("data-dynamicform"));if($(widgetOptions.widgetItem).length>1){var item=$(this).find(widgetOptions.widgetItem).first()[0].outerHTML;$(this).find(widgetOptions.widgetBody).html(item)}}),$template.find("input, textarea, select").each(function(){if($(this).is(":checkbox")||$(this).is(":radio")){var e=$(this).is(":checkbox")?"checkbox":"radio",t=$(this).attr("name"),i=$template.find('input[type="hidden"][name="'+t+'"]').first(),a=$template.find('input[type="'+e+'"][name="'+t+'"]').length;i&&1===a&&($(this).val(1),i.val(0)),$(this).prop("checked",!1)}else $(this).val("")});var yiiActiveFormData=$("#"+widgetOptions.formId).yiiActiveForm("data");return $template.find("."+yiiActiveFormData.settings.errorCssClass).removeClass(yiiActiveFormData.settings.errorCssClass),$template.find("."+yiiActiveFormData.settings.successCssClass).removeClass(yiiActiveFormData.settings.successCssClass),$template},_getWidgetOptionsRoot=function(widgetOptions){return eval($(widgetOptions.widgetBody).parents("div[data-dynamicform]").last().attr("data-dynamicform"))},_getLevel=function(e){var t=e.parents("div[data-dynamicform]").length;return t=0>t?0:t},_count=function(e,t){return e.closest("."+t.widgetContainer).find(t.widgetItem).length},_createIdentifiers=function(e){return new Array(e+2).join("0").split("")},_addItem=function(e,t,i){var a=_count(i,e);a1){$elem.find("div[data-dynamicform]").each(function(){for(var currentWidgetOptions=eval($(this).attr("data-dynamicform")),level=_getLevel($(this)),identifiers=_createIdentifiers(level),numItems=$(this).find(currentWidgetOptions.widgetItem).length,i=1;numItems-1>=i;i++){var aux=identifiers;aux[level]=i,currentWidgetOptions.fields.forEach(function(e){var t=e.id.replace("{}",aux.join("-"));"undefined"!==$("#"+currentWidgetOptions.formId).yiiActiveForm("find",t)&&$("#"+currentWidgetOptions.formId).yiiActiveForm("remove",t)})}});var level=_getLevel($elem.closest("."+widgetOptions.widgetContainer)),widgetOptionsRoot=_getWidgetOptionsRoot(widgetOptions),identifiers=_createIdentifiers(level);identifiers[0]=$(widgetOptionsRoot.widgetItem).length-1,identifiers[level]=count-1,widgetOptions.fields.forEach(function(e){var t=e.id.replace("{}",identifiers.join("-"));"undefined"!==$("#"+widgetOptions.formId).yiiActiveForm("find",t)&&$("#"+widgetOptions.formId).yiiActiveForm("remove",t)})}},_deleteItem=function(e,t,i){var a=_count(i,e);if(a>e.min){$todelete=i.closest(e.widgetItem);var n=$("."+e.widgetContainer).triggerHandler(events.beforeDelete,$todelete);n!==!1&&(_removeValidations($todelete,e,a),$todelete.remove(),_updateAttributes(e),_restoreSpecialJs(e),_fixFormValidaton(e),$("."+e.widgetContainer).triggerHandler(events.afterDelete))}},_updateAttrID=function($elem,index){var widgetOptions=eval($elem.closest("div[data-dynamicform]").attr("data-dynamicform")),id=$elem.attr("id"),newID=id;if(void 0!==id){var matches=id.match(regexID);if(matches&&4===matches.length){matches[2]=matches[2].substring(1,matches[2].length-1);var identifiers=matches[2].split("-");if(identifiers[0]=index,identifiers.length>1){var widgetsOptions=[];$elem.parents("div[data-dynamicform]").each(function(i){widgetsOptions[i]=eval($(this).attr("data-dynamicform"))}),widgetsOptions=widgetsOptions.reverse();for(var i=identifiers.length-1;i>=1;i--)identifiers[i]=$elem.closest(widgetsOptions[i].widgetItem).index()}newID=matches[1]+"-"+identifiers.join("-")+"-"+matches[3],$elem.attr("id",newID)}else newID=id+index,$elem.attr("id",newID)}return id!==newID&&($elem.closest(widgetOptions.widgetItem).find(".field-"+id).each(function(){$(this).removeClass("field-"+id).addClass("field-"+newID)}),$elem.closest(widgetOptions.widgetItem).find("label[for='"+id+"']").attr("for",newID)),newID},_updateAttrName=function($elem,index){var name=$elem.attr("name");if(void 0!==name){var matches=name.match(regexName);if(matches&&4===matches.length){matches[2]=matches[2].replace(/\]\[/g,"-").replace(/\]|\[/g,"");var identifiers=matches[2].split("-");if(identifiers[0]=index,identifiers.length>1){var widgetsOptions=[];$elem.parents("div[data-dynamicform]").each(function(i){widgetsOptions[i]=eval($(this).attr("data-dynamicform"))}),widgetsOptions=widgetsOptions.reverse();for(var i=identifiers.length-1;i>=1;i--)identifiers[i]=$elem.closest(widgetsOptions[i].widgetItem).index()}name=matches[1]+"["+identifiers.join("][")+"]"+matches[3],$elem.attr("name",name)}}return name},_updateAttributes=function(e){var t=_getWidgetOptionsRoot(e);$(t.widgetItem).each(function(e){$(this);$(this).find("*").each(function(){_updateAttrID($(this),e),_updateAttrName($(this),e)})})},_fixFormValidatonInput=function(e,t,i,a){void 0!==t&&(t=$.extend(!0,{},t),t.id=i,t.container=".field-"+i,t.input="#"+i,t.name=a,t.value=$("#"+i).val(),t.status=0,"undefined"!==$("#"+e.formId).yiiActiveForm("find",i)&&$("#"+e.formId).yiiActiveForm("remove",i),$("#"+e.formId).yiiActiveForm("add",t))},_fixFormValidaton=function(widgetOptions){var widgetOptionsRoot=_getWidgetOptionsRoot(widgetOptions);$(widgetOptionsRoot.widgetBody).find("input, textarea, select").each(function(){var id=$(this).attr("id"),name=$(this).attr("name");if(void 0!==id&&void 0!==name){currentWidgetOptions=eval($(this).closest("div[data-dynamicform]").attr("data-dynamicform"));var matches=id.match(regexID);if(matches&&4===matches.length){matches[2]=matches[2].substring(1,matches[2].length-1);var level=_getLevel($(this)),identifiers=_createIdentifiers(level-1),baseID=matches[1]+"-"+identifiers.join("-")+"-"+matches[3],attribute=$("#"+currentWidgetOptions.formId).yiiActiveForm("find",baseID);_fixFormValidatonInput(currentWidgetOptions,attribute,id,name)}}})},_restoreSpecialJs=function(widgetOptions){var widgetOptionsRoot=_getWidgetOptionsRoot(widgetOptions),$hasInputmask=$(widgetOptionsRoot.widgetItem).find("[data-plugin-inputmask]");$hasInputmask.length>0&&$hasInputmask.each(function(){$(this).inputmask("remove"),$(this).inputmask(eval($(this).attr("data-plugin-inputmask")))});var $hasDatepicker=$(widgetOptionsRoot.widgetItem).find("[data-krajee-datepicker]");$hasDatepicker.length>0&&$hasDatepicker.each(function(){$(this).parent().removeData().datepicker("remove"),$(this).parent().datepicker(eval($(this).attr("data-krajee-datepicker")))});var $hasTimepicker=$(widgetOptionsRoot.widgetItem).find("[data-krajee-timepicker]");$hasTimepicker.length>0&&$hasTimepicker.each(function(){$(this).removeData().off(),$(this).parent().find(".bootstrap-timepicker-widget").remove(),$(this).unbind(),$(this).timepicker(eval($(this).attr("data-krajee-timepicker")))});var $hasMaskmoney=$(widgetOptionsRoot.widgetItem).find("[data-krajee-maskMoney]");$hasMaskmoney.length>0&&$hasMaskmoney.each(function(){$(this).parent().find("input").removeData().off();var id="#"+$(this).attr("id"),displayID=id+"-disp";$(displayID).maskMoney("destroy"),$(displayID).maskMoney(eval($(this).attr("data-krajee-maskMoney"))),$(displayID).maskMoney("mask",parseFloat($(id).val())),$(displayID).on("change",function(){var e=$(displayID).maskMoney("unmasked")[0];$(id).val(e),$(id).trigger("change")})});var $hasFileinput=$(widgetOptionsRoot.widgetItem).find("[data-krajee-fileinput]");$hasFileinput.length>0&&$hasFileinput.each(function(){$(this).fileinput(eval($(this).attr("data-krajee-fileinput")))});var $hasTouchSpin=$(widgetOptionsRoot.widgetItem).find("[data-krajee-TouchSpin]");$hasTouchSpin.length>0&&$hasTouchSpin.each(function(){$(this).TouchSpin("destroy"),$(this).TouchSpin(eval($(this).attr("data-krajee-TouchSpin")))});var $hasSpectrum=$(widgetOptionsRoot.widgetItem).find("[data-krajee-spectrum]");$hasSpectrum.length>0&&$hasSpectrum.each(function(){var id="#"+$(this).attr("id"),sourceID=id+"-source";$(sourceID).spectrum("destroy"),$(sourceID).unbind(),$(id).unbind();var configSpectrum=eval($(this).attr("data-krajee-spectrum"));configSpectrum.change=function(e){jQuery(id).val(e.toString())},$(sourceID).attr("name",$(sourceID).attr("id")),$(sourceID).spectrum(configSpectrum),$(sourceID).spectrum("set",jQuery(id).val()),$(id).on("change",function(){$(sourceID).spectrum("set",jQuery(id).val())})});var $hasDepdrop=$(widgetOptionsRoot.widgetItem).find("[data-krajee-depdrop]");$hasDepdrop.length>0&&$hasDepdrop.each(function(){$(this).removeData().off(),$(this).unbind();var configDepdrop=eval($(this).attr("data-krajee-depdrop")),inputID=$(this).attr("id"),matchID=inputID.match(regex);if(matchID&&4===matchID.length)for(index=0;index0&&$hasSelect2.each(function(){var id=$(this).attr("id"),configSelect2=eval($(this).attr("data-krajee-select2"));$(this).select2("destroy"),$.when($("#"+id).select2(configSelect2)).done(initSelect2Loading(id)),$("#"+id).on("select2-open",function(){initSelect2DropStyle(id)}),$(this).attr("data-krajee-depdrop")&&($(this).on("depdrop.beforeChange",function(e,i,v){var configDepdrop=eval($(this).attr("data-krajee-depdrop")),loadingText=configDepdrop.loadingText?configDepdrop.loadingText:"Loading ...";$("#"+id).select2("data",{text:loadingText})}),$(this).on("depdrop.change",function(){$("#"+id).select2("val",$("#"+id).val())}))})}}(window.jQuery);