【问题标题】:Select2 and wbraganca/yii2-dynamicform not working together in Yii2Select2 和 wbraganca/yii2-dynamicform 在 Yii2 中不能一起工作
【发布时间】:2016-08-14 07:16:41
【问题描述】:

我正在尝试在 wbraganca/yii2-dynamicform 中使用 Select2。第一行工作正常,但是当我单击加号按钮时,select2 字段继续旋转。 屏幕截图 - 。我试过 - https://github.com/wbraganca/yii2-dynamicform/issues/76https://github.com/TimNZ/yii2-dynamicform/blob/master/src/assets/yii2-dynamic-form.js 但似乎没有用。

我在 vendor/wbragance/yii2-dynamicform/asset/yii2-dynamic-form.js 中的代码看起来像 -

// "kartik-v/yii2-widget-depdrop"
        var $hasDepdrop = $(widgetOptionsRoot.widgetItem).find('[data-krajee-depdrop]');
        if ($hasDepdrop.length > 0) {
            $hasDepdrop.each(function() {
                if ($(this).data('select2') === undefined) {
                    $(this).removeData().off();
                    $(this).unbind();
                    _restoreKrajeeDepdrop($(this));
                }
            });
        }

        // "kartik-v/yii2-widget-select2"
        var $hasSelect2 = $(widgetOptionsRoot.widgetItem).find('[data-krajee-select2]');
        if ($hasSelect2.length > 0) {
            $hasSelect2.each(function() {
                var id = $(this).attr('id');
                var configSelect2 = eval($(this).attr('data-krajee-select2'));

                if ($(this).data('select2')) {
                    $(this).select2('destroy');
                }

                var configDepdrop = $(this).data('depdrop');
                if (configDepdrop) {
                    configDepdrop = $.extend(true, {}, configDepdrop);
                    $(this).removeData().off();
                    $(this).unbind();
                    _restoreKrajeeDepdrop($(this));
                }
                var s2LoadingFunc = typeof initSelect2Loading != 'undefined' ? initSelect2Loading : initS2Loading;
                var s2OpenFunc = typeof initSelect2DropStyle != 'undefined' ? initSelect2Loading : initS2Loading;
                $.when($('#' + id).select2(configSelect2)).done(s2LoadingFunc(id, '.select2-container--krajee'));

                var kvClose = 'kv_close_' + id.replace(/\-/g, '_');

                $('#' + id).on('select2:opening', function(ev) {
                    s2OpenFunc(id, kvClose, ev);
                });

                $('#' + id).on('select2:unselect', function() {
                    window[kvClose] = true;
                });

               if (configDepdrop) {
                    var loadingText = (configDepdrop.loadingText) ? configDepdrop.loadingText : 'Loading ...';
                    initDepdropS2(id, loadingText);
                }
            });
        }
    };

更新 -

I've changed the yii2-dynamic-form.js as following 
// "kartik-v/yii2-widget-depdrop"
        var $hasDepdrop = $(widgetOptionsRoot.widgetItem).find('[data-krajee-depdrop]');
        if ($hasDepdrop.length > 0) {
            $hasDepdrop.each(function() {
                if ($(this).data('select2') === undefined) {
                    $(this).removeData().off();
                    $(this).unbind();
                    _restoreKrajeeDepdrop($(this));
                }

            });
        }

        // "kartik-v/yii2-widget-select2"
        var $hasSelect2 = $(widgetOptionsRoot.widgetItem).find('[data-krajee-select2]');
        if ($hasSelect2.length > 0) {
            $hasSelect2.each(function() {
                var id = $(this).attr('id');
                var configSelect2 = eval($(this).attr('data-krajee-select2'));

                    if ($(this).data('select2')) {
                    $(this).select2('destroy');
                }

                var configDepdrop = $(this).data('depdrop');
                if (configDepdrop) {
                    configDepdrop = $.extend(true, {}, configDepdrop);
                    $(this).removeData().off();
                    $(this).unbind();
                    _restoreKrajeeDepdrop($(this));
                }

                var s2LoadingFunc = typeof initSelect2Loading != 'undefined' ? initSelect2Loading : initS2Loading;
                var s2OpenFunc = typeof initSelect2DropStyle != 'undefined' ? initSelect2Loading : initS2Loading;
                $.when($('#' + id).select2(configSelect2)).done(initS2Loading(id, '.select2-container--krajee'));

                    var kvClose = 'kv_close_' + id.replace(/\-/g, '_');

                    $('#' + id).on('select2:opening', function(ev) {
                        //initSelect2DropStyle(id, kvClose, ev);
                        s2OpenFunc(id, kvClose, ev);
                });
                $('#' + id).on('select2:unselect', function() {
                    window[kvClose] = true;
                });

                if (configDepdrop) {
                    var loadingText = (configDepdrop.loadingText) ? configDepdrop.loadingText : 'Loading ...';
                    initDepdropS2(id, loadingText);
                }
            });
        }

现在没有错误消息,但我收到以下屏幕 -

我正在使用 Kartik Depdrop 和 Select2。只有在第一行,两者似乎都在工作。在后面只有 select2 正在使用它上面的旋转标志。

【问题讨论】:

    标签: yii2


    【解决方案1】:

    这是我的解决方案:

    我修改了dynamic-form.js如下:

    /**
     * yii2-dynamic-form
     *
     * A jQuery plugin to clone form elements in a nested manner, maintaining accessibility.
     *
     * @author Wanderson Bragança <wanderson.wbc@gmail.com>
     */
    (function ($) {
        var pluginName = 'yiiDynamicForm';
    
        var regexID = /^(.+?)([-\d-]{1,})(.+)$/i;
    
        var regexName = /(^.+?)([\[\d{1,}\]]{1,})(\[.+\]$)/i;
    
        $.fn.yiiDynamicForm = function (method) {
            if (methods[method]) {
                return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
            } else if (typeof method === 'object' || !method) {
                return methods.init.apply(this, arguments);
            } else {
                $.error('Method ' + method + ' does not exist on jQuery.yiiDynamicForm');
                return false;
            }
        };
    
        var events = {
            beforeInsert: 'beforeInsert',
            afterInsert: 'afterInsert',
            beforeDelete: 'beforeDelete',
            afterDelete: 'afterDelete',
            limitReached: 'limitReached'
        };
    
        var methods = {
            init: function (widgetOptions) {
                return this.each(function () {
                    widgetOptions.template = _parseTemplate(widgetOptions);
                });
            },
    
            addItem: function (widgetOptions, e, $elem) {
               _addItem(widgetOptions, e, $elem);
            },
    
            deleteItem: function (widgetOptions, e, $elem) {
               _deleteItem(widgetOptions, e, $elem);
            },
    
            updateContainer: function () {
                var widgetOptions = eval($(this).attr('data-dynamicform'));
                _updateAttributes(widgetOptions);
                _restoreSpecialJs(widgetOptions);
                _fixFormValidaton(widgetOptions);
            }
        };
    
        var _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() {
                $(this).val('');
            });
    
            $template.find('input[type="checkbox"], input[type="radio"]').each(function() {
                var inputName = $(this).attr('name');
                var $inputHidden = $template.find('input[type="hidden"][name="' + inputName + '"]').first();
                if ($inputHidden) {
                    $(this).val(1);
                    $inputHidden.val(0);
                }
            });
    
            return $template;
        };
    
        var _getWidgetOptionsRoot = function(widgetOptions) {
            return eval($(widgetOptions.widgetBody).parents('div[data-dynamicform]').last().attr('data-dynamicform'));
        };
    
        var _getLevel = function($elem) {
            var level = $elem.parents('div[data-dynamicform]').length;
            level = (level < 0) ? 0 : level;
            return level;
        };
    
        var _count = function($elem, widgetOptions) {
            return $elem.closest('.' + widgetOptions.widgetContainer).find(widgetOptions.widgetItem).length;
        };
    
        var _createIdentifiers = function(level) {
            return new Array(level + 2).join('0').split('');
        };
    
        var _addItem = function(widgetOptions, e, $elem) {
            var count = _count($elem, widgetOptions);
    
            if (count < widgetOptions.limit) {
                $toclone = widgetOptions.template;
                $newclone = $toclone.clone(false, false);
    
                if (widgetOptions.insertPosition === 'top') {
                    $elem.closest('.' + widgetOptions.widgetContainer).find(widgetOptions.widgetBody).prepend($newclone);
                } else {
                    $elem.closest('.' + widgetOptions.widgetContainer).find(widgetOptions.widgetBody).append($newclone);
                }
    
                _updateAttributes(widgetOptions);
                _restoreSpecialJs(widgetOptions);
                _fixFormValidaton(widgetOptions);
                $elem.closest('.' + widgetOptions.widgetContainer).triggerHandler(events.afterInsert, $newclone);
            } else {
                // trigger a custom event for hooking
                $elem.closest('.' + widgetOptions.widgetContainer).triggerHandler(events.limitReached, widgetOptions.limit);
            }
        };
    
        var _removeValidations = function($elem, widgetOptions, count) {
            if (count > 1) {
                $elem.find('div[data-dynamicform]').each(function() {
                    var currentWidgetOptions = eval($(this).attr('data-dynamicform'));
                    var level           = _getLevel($(this));
                    var identifiers     = _createIdentifiers(level);
                    var numItems        = $(this).find(currentWidgetOptions.widgetItem).length;
    
                    for (var i = 1; i <= numItems -1; i++) {
                        var aux = identifiers;
                        aux[level] = i;
                        currentWidgetOptions.fields.forEach(function(input) {
                            var id = input.id.replace("{}", aux.join('-'));
                            if ($("#" + currentWidgetOptions.formId).yiiActiveForm("find", id) !== "undefined") {
                                $("#" + currentWidgetOptions.formId).yiiActiveForm("remove", id);
                            }
                        });
                    }
                });
    
                var level          = _getLevel($elem.closest('.' + widgetOptions.widgetContainer));
                var widgetOptionsRoot       = _getWidgetOptionsRoot(widgetOptions);
                var identifiers    = _createIdentifiers(level);
                identifiers[0]     = $(widgetOptionsRoot.widgetItem).length - 1;
                identifiers[level] = count - 1;
    
                widgetOptions.fields.forEach(function(input) {
                    var id = input.id.replace("{}", identifiers.join('-'));
                    if ($("#" + widgetOptions.formId).yiiActiveForm("find", id) !== "undefined") {
                        $("#" + widgetOptions.formId).yiiActiveForm("remove", id);
                    }
                });
            }
        };
    
        var _deleteItem = function(widgetOptions, e, $elem) {
            var count = _count($elem, widgetOptions);
    
            if (count > widgetOptions.min) {
                $todelete = $elem.closest(widgetOptions.widgetItem);
    
                // trigger a custom event for hooking
                var eventResult = $('.' + widgetOptions.widgetContainer).triggerHandler(events.beforeDelete, $todelete);
                if (eventResult !== false) {
                    _removeValidations($todelete, widgetOptions, count);
                    $todelete.remove();
                    _updateAttributes(widgetOptions);
                    _restoreSpecialJs(widgetOptions);
                    _fixFormValidaton(widgetOptions);
                    $('.' + widgetOptions.widgetContainer).triggerHandler(events.afterDelete);
                }
            }
        };
    
        var _updateAttrID = function($elem, index) {
            var widgetOptions = eval($elem.closest('div[data-dynamicform]').attr('data-dynamicform'));
            var id            = $elem.attr('id');
            var newID         = id;
    
            if (id !== undefined) {
                var matches = id.match(regexID);
                if (matches && matches.length === 4) {
                    matches[2] = matches[2].substring(1, matches[2].length - 1);
                    var identifiers = matches[2].split('-');
                    identifiers[0] = index;
    
                    if (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);
                }
            }
    
            if (id !== newID) {
                $elem.closest(widgetOptions.widgetItem).find('.field-' + id).each(function() {
                    $(this).removeClass('field-' + id).addClass('field-' + newID);
                });
                // update "for" attribute
                $elem.closest(widgetOptions.widgetItem).find("label[for='" + id + "']").attr('for',newID); 
            }
    
            return newID;
        };
    
        var _updateAttrName = function($elem, index) {
            var name = $elem.attr('name');
    
            if (name !== undefined) {
                var matches = name.match(regexName);
    
                if (matches && matches.length === 4) {
                    matches[2] = matches[2].replace(/\]\[/g, "-").replace(/\]|\[/g, '');
                    var identifiers = matches[2].split('-');
                    identifiers[0] = index;
    
                    if (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;
        };
    
        var _updateAttributes = function(widgetOptions) {
            var widgetOptionsRoot = _getWidgetOptionsRoot(widgetOptions);
    
            $(widgetOptionsRoot.widgetItem).each(function(index) {
                var $item = $(this);
                $(this).find('*').each(function() {
                    // update "id" attribute
                    _updateAttrID($(this), index);
    
                    // update "name" attribute
                    _updateAttrName($(this), index);
                });
            });
        };
    
        var _fixFormValidatonInput = function(widgetOptions, attribute, id, name) {
            if (attribute !== undefined) {
                attribute           = $.extend(true, {}, attribute);
                attribute.id        = id;
                attribute.container = ".field-" + id;
                attribute.input     = "#" + id;
                attribute.name      = name;
                attribute.value     = $("#" + id).val();
                attribute.status    = 0;
    
                if ($("#" + widgetOptions.formId).yiiActiveForm("find", id) !== "undefined") {
                    $("#" + widgetOptions.formId).yiiActiveForm("remove", id);
                }
    
                $("#" + widgetOptions.formId).yiiActiveForm("add", attribute);
            }
        };
    
        var _fixFormValidaton = function(widgetOptions) {
            var widgetOptionsRoot = _getWidgetOptionsRoot(widgetOptions);
    
            $(widgetOptionsRoot.widgetBody).find('input, textarea, select').each(function() {
                var id   = $(this).attr('id');
                var name = $(this).attr('name');
    
                if (id !== undefined && name !== undefined) {
                    currentWidgetOptions = eval($(this).closest('div[data-dynamicform]').attr('data-dynamicform'));
                    var matches = id.match(regexID);
    
                    if (matches && matches.length === 4) {
                        matches[2]      = matches[2].substring(1, matches[2].length - 1);
                        var level       = _getLevel($(this));
                        var identifiers = _createIdentifiers(level -1);
                        var baseID      = matches[1] + '-' + identifiers.join('-') + '-' + matches[3];
                        var attribute   = $("#" + currentWidgetOptions.formId).yiiActiveForm("find", baseID);
                        _fixFormValidatonInput(currentWidgetOptions, attribute, id, name);
                    }
                }
            });
        };
    
        var _restoreSpecialJs = function(widgetOptions) {
            var widgetOptionsRoot = _getWidgetOptionsRoot(widgetOptions);
    
            // "kartik-v/yii2-widget-datepicker"
            var $hasDatepicker = $(widgetOptionsRoot.widgetItem).find('[data-krajee-datepicker]');
            if ($hasDatepicker.length > 0) {
                $hasDatepicker.each(function() {
                    $(this).parent().removeData().datepicker('remove');
                    $(this).parent().datepicker(eval($(this).attr('data-krajee-datepicker')));
                });
            }
    
            // "kartik-v/yii2-widget-timepicker"
            var $hasTimepicker = $(widgetOptionsRoot.widgetItem).find('[data-krajee-timepicker]');
            if ($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')));
                });
            }
    
            // "kartik-v/yii2-money"
            var $hasMaskmoney = $(widgetOptionsRoot.widgetItem).find('[data-krajee-maskMoney]');
            if ($hasMaskmoney.length > 0) {
                $hasMaskmoney.each(function() {
                    $(this).parent().find('input').removeData().off();
                    var id = '#' + $(this).attr('id');
                    var 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 numDecimal = $(displayID).maskMoney('unmasked')[0];
                        $(id).val(numDecimal);
                        $(id).trigger('change');
                    });
                });
            }
    
            // "kartik-v/yii2-widget-fileinput"
            var $hasFileinput = $(widgetOptionsRoot.widgetItem).find('[data-krajee-fileinput]');
            if ($hasFileinput.length > 0) {
                $hasFileinput.each(function() {
                    $(this).fileinput(eval($(this).attr('data-krajee-fileinput')));
                });
            }
    
            // "kartik-v/yii2-widget-touchspin"
            var $hasTouchSpin = $(widgetOptionsRoot.widgetItem).find('[data-krajee-TouchSpin]');
            if ($hasTouchSpin.length > 0) {
                $hasTouchSpin.each(function() {
                    $(this).TouchSpin('destroy');
                    $(this).TouchSpin(eval($(this).attr('data-krajee-TouchSpin')));
                });
            }
    
            // "kartik-v/yii2-widget-colorinput"
            var $hasSpectrum = $(widgetOptionsRoot.widgetItem).find('[data-krajee-spectrum]');
            if ($hasSpectrum.length > 0) {
                $hasSpectrum.each(function() {
                    var id = '#' + $(this).attr('id');
                    var sourceID  = id + '-source';
                    $(sourceID).spectrum('destroy');
                    $(sourceID).unbind();
                    $(id).unbind();
                    var configSpectrum = eval($(this).attr('data-krajee-spectrum'));
                    configSpectrum.change = function (color) {
                        jQuery(id).val(color.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 _restoreKrajeeDepdrop = function($elem) {
                var configDepdrop = $.extend(true, {}, eval($elem.attr('data-krajee-depdrop')));
                var inputID = $elem.attr('id');
                var matchID = inputID.match(regexID);
    
                if (matchID && matchID.length === 4) {
                    for (index = 0; index < configDepdrop.depends.length; ++index) {
                        var match = configDepdrop.depends[index].match(regexID);
                        if (match && match.length === 4) {
                            configDepdrop.depends[index] = match[1] + matchID[2] + match[3];
                        }
                    }
                }
                $elem.depdrop(configDepdrop);
            };
    
            // "kartik-v/yii2-widget-depdrop"
            var _restoreKrajeeDepdrop = function($elem) {
                var configDepdrop = $.extend(true, {}, eval($elem.attr('data-krajee-depdrop')));
                var inputID = $elem.attr('id');
                var matchID = inputID.match(regexID);
    
                if (matchID && matchID.length === 4) {
                    for (index = 0; index < configDepdrop.depends.length; ++index) {
                        var match = configDepdrop.depends[index].match(regexID);
                        if (match && match.length === 4) {
                            configDepdrop.depends[index] = match[1] + matchID[2] + match[3];
                        }
                    }
                }
                $elem.depdrop(configDepdrop);
            };
            var $hasDepdrop = $(widgetOptionsRoot.widgetItem).find('[data-krajee-depdrop]');
            if ($hasDepdrop.length > 0) {
                $hasDepdrop.each(function() {
                    if ($(this).data('select2') === undefined) {
                         $(this).removeData().off();
                         $(this).unbind();
                         _restoreKrajeeDepdrop($(this));
                      }
                    var configDepdrop = eval($(this).attr('data-krajee-depdrop'));
                    $(this).depdrop(configDepdrop);
                });
            }
    
            // "kartik-v/yii2-widget-select2"
            var $hasSelect2 = $(widgetOptionsRoot.widgetItem).find('[data-krajee-select2]');
            if ($hasSelect2.length > 0) {
                $hasSelect2.each(function() {
                    var id = $(this).attr('id');
                    var configSelect2 = eval($(this).attr('data-krajee-select2'));
                    $.when($('#' + id).select2(configSelect2)).done(initS2Loading(id));
                    $('#' + id).on('select2-open', function() {
                        initSelect2DropStyle(id)
                    });
                    if ($(this).attr('data-krajee-depdrop')) {
                        $(this).on('depdrop.beforeChange', function(e,i,v) {
                            var configDepdrop = eval($(this).attr('data-krajee-depdrop'));
                            var loadingText = (configDepdrop.loadingText)? configDepdrop.loadingText : 'Loading ...';
                            $('#' + id).select2('data', {text: loadingText});
                        });
                        $(this).on('depdrop.change', function(e,i,v,c) {
                            $('#' + id).select2('val', $('#' + id).val());
                        });
                    }
                });
            }
        };
    
    })(window.jQuery);
    

    对我来说效果很好。

    【讨论】:

      【解决方案2】:

      我找到了删除 select2 上的旋转图标的解决方案。我已经从我的 _form 中的 select2 小部件中删除了“id”,这解决了这个问题。

      【讨论】:

        【解决方案3】:

        没有对供应商的代码进行更改,而是使用带有问题修复的新存储库。

        Link =&gt; https://packagist.org/packages/vivekmarakana/yii2-dynamicform

        任意运行

        php composer.phar 需要 --prefer-dist vivekmarakana/yii2-dynamicform "*"

        或添加

        "vivekmarakana/yii2-dynamicform": "*"

        到 composer.json 文件的 require 部分。

        【讨论】:

          猜你喜欢
          • 2015-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-31
          • 2017-10-16
          • 1970-01-01
          • 2016-09-07
          • 1970-01-01
          相关资源
          最近更新 更多