删除jQuery ASM select中的初始选定项

时间:2010-07-28 10:38:00

标签: jquery multiple-select asmselect

我正在使用相当精彩的jQuery多选插件ASM select

这个插件非常接近我的需求,我必须尝试修复我能找到的唯一错误。

在初始加载时,选择器会检查具有“selected”属性的所有元素并选择它们。这很好,除非没有任何属性“选择”它选择第一个属性。

如何阻止它这样做?我不希望最初选择的任何东西为9/10次,这将是错误的选择。

我不是jQuery编码器,已经查看了代码并找到了几个引用来构建第一个选择项并摆弄它们,但没有取得任何成功。

我通常不这样做,但看到我完全不知道从哪里开始,这里是插件的代码。

/*
 * Alternate Select Multiple (asmSelect) 1.0.4a beta - jQuery Plugin
 * http://www.ryancramer.com/projects/asmselect/
 * 
 * Copyright (c) 2009 by Ryan Cramer - http://www.ryancramer.com
 * 
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 */

(function($) {

    $.fn.asmSelect = function(customOptions) {

        var options = {

            listType: 'ol',                     // Ordered list 'ol', or unordered list 'ul'
            sortable: false,                    // Should the list be sortable?
            highlight: false,                   // Use the highlight feature? 
            animate: false,                     // Animate the the adding/removing of items in the list?
            addItemTarget: 'bottom',                // Where to place new selected items in list: top or bottom
            hideWhenAdded: false,                   // Hide the option when added to the list? works only in FF
            debugMode: false,                   // Debug mode keeps original select visible 

            removeLabel: 'remove',                  // Text used in the "remove" link
            highlightAddedLabel: 'Added: ',             // Text that precedes highlight of added item
            highlightRemovedLabel: 'Removed: ',         // Text that precedes highlight of removed item

            containerClass: 'asmContainer',             // Class for container that wraps this widget
            selectClass: 'asmSelect',               // Class for the newly created <select>
            optionDisabledClass: 'asmOptionDisabled',       // Class for items that are already selected / disabled
            listClass: 'asmList',                   // Class for the list ($ol)
            listSortableClass: 'asmListSortable',           // Another class given to the list when it is sortable
            listItemClass: 'asmListItem',               // Class for the <li> list items
            listItemLabelClass: 'asmListItemLabel',         // Class for the label text that appears in list items
            removeClass: 'asmListItemRemove',           // Class given to the "remove" link
            highlightClass: 'asmHighlight'              // Class given to the highlight <span>

            };

        $.extend(options, customOptions); 

        return this.each(function(index) {

            var $original = $(this);                // the original select multiple
            var $container;                     // a container that is wrapped around our widget
            var $select;                        // the new select we have created
            var $ol;                        // the list that we are manipulating
            var buildingSelect = false;                 // is the new select being constructed right now?
            var ieClick = false;                    // in IE, has a click event occurred? ignore if not
            var ignoreOriginalChangeEvent = false;          // originalChangeEvent bypassed when this is true

            function init() {

                // initialize the alternate select multiple

                // this loop ensures uniqueness, in case of existing asmSelects placed by ajax (1.0.3)
                while($("#" + options.containerClass + index).size() > 0) index++; 

                $select = $("<select></select>")
                    .addClass(options.selectClass)
                    .attr('name', options.selectClass + index)
                    .attr('id', options.selectClass + index); 

                $selectRemoved = $("<select></select>"); 

                $ol = $("<" + options.listType + "></" + options.listType + ">")
                    .addClass(options.listClass)
                    .attr('id', options.listClass + index); 

                $container = $("<div></div>")
                    .addClass(options.containerClass) 
                    .attr('id', options.containerClass + index); 

                buildSelect();

                $select.change(selectChangeEvent)
                    .click(selectClickEvent); 

                $original.change(originalChangeEvent)
                    .wrap($container).before($select).before($ol);

                if(options.sortable) makeSortable();

                if($.browser.msie && $.browser.version < 8) $ol.css('display', 'inline-block'); // Thanks Matthew Hutton
            }

            function makeSortable() {

                // make any items in the selected list sortable
                // requires jQuery UI sortables, draggables, droppables

                $ol.sortable({
                    items: 'li.' + options.listItemClass,
                    handle: '.' + options.listItemLabelClass,
                    axis: 'y',
                    update: function(e, data) {

                        var updatedOptionId;

                        $(this).children("li").each(function(n) {

                            $option = $('#' + $(this).attr('rel')); 

                            if($(this).is(".ui-sortable-helper")) {
                                updatedOptionId = $option.attr('id'); 
                                return;
                            }

                            $original.append($option); 
                        }); 

                        if(updatedOptionId) triggerOriginalChange(updatedOptionId, 'sort'); 
                    }

                }).addClass(options.listSortableClass); 
            }

            function selectChangeEvent(e) {

                // an item has been selected on the regular select we created
                // check to make sure it's not an IE screwup, and add it to the list

                if($.browser.msie && $.browser.version < 7 && !ieClick) return;
                var id = $(this).children("option:selected").slice(0,1).attr('rel'); 
                addListItem(id);    
                ieClick = false; 
                triggerOriginalChange(id, 'add'); // for use by user-defined callbacks
            }

            function selectClickEvent() {

                // IE6 lets you scroll around in a select without it being pulled down
                // making sure a click preceded the change() event reduces the chance
                // if unintended items being added. there may be a better solution?

                ieClick = true; 
            }

            function originalChangeEvent(e) {

                // select or option change event manually triggered
                // on the original <select multiple>, so rebuild ours

                if(ignoreOriginalChangeEvent) {
                    ignoreOriginalChangeEvent = false; 
                    return; 
                }

                $select.empty();
                $ol.empty();
                buildSelect();

                // opera has an issue where it needs a force redraw, otherwise
                // the items won't appear until something else forces a redraw
                if($.browser.opera) $ol.hide().fadeIn("fast");
            }

            function buildSelect() {

                // build or rebuild the new select that the user
                // will select items from

                buildingSelect = true; 

                // add a first option to be the home option / default selectLabel
                $select.prepend("<option>" + $original.attr('title') + "</option>"); 

                $original.children("option").each(function(n) {

                    var $t = $(this); 
                    var id; 

                    if(!$t.attr('id')) $t.attr('id', 'asm' + index + 'option' + n); 
                    id = $t.attr('id'); 

                    if($t.is(":selected")) {
                        addListItem(id); 
                        addSelectOption(id, true);                      
                    } else {
                        addSelectOption(id); 
                    }
                });

                if(!options.debugMode) $original.hide(); // IE6 requires this on every buildSelect()
                selectFirstItem();
                buildingSelect = false; 
            }

            function addSelectOption(optionId, disabled) {

                // add an <option> to the <select>
                // used only by buildSelect()

                if(disabled == undefined) var disabled = false; 

                var $O = $('#' + optionId); 
                var $option = $("<option>" + $O.text() + "</option>")
                    .val($O.val())
                    .attr('rel', optionId);

                if(disabled) disableSelectOption($option); 

                $select.append($option); 
            }

            function selectFirstItem() {

                // select the firm item from the regular select that we created

                $select.children(":eq(0)").attr("selected", true); 
            }

            function disableSelectOption($option) {

                // make an option disabled, indicating that it's already been selected
                // because safari is the only browser that makes disabled items look 'disabled'
                // we apply a class that reproduces the disabled look in other browsers

                $option.addClass(options.optionDisabledClass)
                    .attr("selected", false)
                    .attr("disabled", true);

                if(options.hideWhenAdded) $option.hide();
                if($.browser.msie) $select.hide().show(); // this forces IE to update display
            }

            function enableSelectOption($option) {

                // given an already disabled select option, enable it

                $option.removeClass(options.optionDisabledClass)
                    .attr("disabled", false);

                if(options.hideWhenAdded) $option.show();
                if($.browser.msie) $select.hide().show(); // this forces IE to update display
            }

            function addListItem(optionId) {

                // add a new item to the html list

                var $O = $('#' + optionId); 

                if(!$O) return; // this is the first item, selectLabel

                var $removeLink = $("<a></a>")
                    .attr("href", "#")
                    .addClass(options.removeClass)
                    .prepend(options.removeLabel)
                    .click(function() { 
                        dropListItem($(this).parent('li').attr('rel')); 
                        return false; 
                    }); 

                var $itemLabel = $("<span></span>")
                    .addClass(options.listItemLabelClass)
                    .html($O.html()); 

                var $item = $("<li></li>")
                    .attr('rel', optionId)
                    .addClass(options.listItemClass)
                    .append($itemLabel)
                    .append($removeLink)
                    .hide();

                if(!buildingSelect) {
                    if($O.is(":selected")) return; // already have it
                    $O.attr('selected', true); 
                }

                if(options.addItemTarget == 'top' && !buildingSelect) {
                    $ol.prepend($item); 
                    if(options.sortable) $original.prepend($O); 
                } else {
                    $ol.append($item); 
                    if(options.sortable) $original.append($O); 
                }

                addListItemShow($item); 

                disableSelectOption($("[rel=" + optionId + "]", $select));

                if(!buildingSelect) {
                    setHighlight($item, options.highlightAddedLabel); 
                    selectFirstItem();
                    if(options.sortable) $ol.sortable("refresh");   
                }

            }

            function addListItemShow($item) {

                // reveal the currently hidden item with optional animation
                // used only by addListItem()

                if(options.animate && !buildingSelect) {
                    $item.animate({
                        opacity: "show",
                        height: "show"
                    }, 100, "swing", function() { 
                        $item.animate({
                            height: "+=2px"
                        }, 50, "swing", function() {
                            $item.animate({
                                height: "-=2px"
                            }, 25, "swing"); 
                        }); 
                    }); 
                } else {
                    $item.show();
                }
            }

            function dropListItem(optionId, highlightItem) {

                // remove an item from the html list

                if(highlightItem == undefined) var highlightItem = true; 
                var $O = $('#' + optionId); 

                $O.attr('selected', false); 
                $item = $ol.children("li[rel=" + optionId + "]");

                dropListItemHide($item); 
                enableSelectOption($("[rel=" + optionId + "]", options.removeWhenAdded ? $selectRemoved : $select));

                if(highlightItem) setHighlight($item, options.highlightRemovedLabel); 

                triggerOriginalChange(optionId, 'drop'); 

            }

            function dropListItemHide($item) {

                // remove the currently visible item with optional animation
                // used only by dropListItem()

                if(options.animate && !buildingSelect) {

                    $prevItem = $item.prev("li");

                    $item.animate({
                        opacity: "hide",
                        height: "hide"
                    }, 100, "linear", function() {
                        $prevItem.animate({
                            height: "-=2px"
                        }, 50, "swing", function() {
                            $prevItem.animate({
                                height: "+=2px"
                            }, 100, "swing"); 
                        }); 
                        $item.remove(); 
                    }); 

                } else {
                    $item.remove(); 
                }
            }

            function setHighlight($item, label) {

                // set the contents of the highlight area that appears
                // directly after the <select> single
                // fade it in quickly, then fade it out

                if(!options.highlight) return; 

                $select.next("#" + options.highlightClass + index).remove();

                var $highlight = $("<span></span>")
                    .hide()
                    .addClass(options.highlightClass)
                    .attr('id', options.highlightClass + index)
                    .html(label + $item.children("." + options.listItemLabelClass).slice(0,1).text()); 

                $select.after($highlight); 

                $highlight.fadeIn("fast", function() {
                    setTimeout(function() { $highlight.fadeOut("slow"); }, 50); 
                }); 
            }

            function triggerOriginalChange(optionId, type) {

                // trigger a change event on the original select multiple
                // so that other scripts can pick them up

                ignoreOriginalChangeEvent = true; 
                $option = $("#" + optionId); 

                $original.trigger('change', [{
                    'option': $option,
                    'value': $option.val(),
                    'id': optionId,
                    'item': $ol.children("[rel=" + optionId + "]"),
                    'type': type
                }]); 
            }

            init();
        });
    };

})(jQuery); 

我希望有人能解决这个问题。

2 个答案:

答案 0 :(得分:2)

看来这个插件没有错,而是操作员......我

<select multiple name="options[]" id="optionsSelect">

未指定multiple属性会导致ASM选择将选择框视为普通选择框,当然总是选择一个选项。

卫生署。

我觉得是时候睡觉了。

答案 1 :(得分:0)

替换行():

        addListItem(id); 
        addSelectOption(id, true);                      

以下内容:

        $t.prop('selected', false);
        addSelectOption(id);

此外,您需要替换:

        $O.attr('selected', true);

使用:

        $O.prop('selected', true);

注意:

  1. 这将删除使用ASM select的所有多个选择字段的预选选项。
  2. 这将阻止您完全定义预先选择的字段!
  3. 代码行是:184-185(可能因使用的asm Select版本而异)函数是:buildSelect。而第274行的功能是:addListItem
  4. 希望它有所帮助!