删除 jQuery ASM select 中的初始选定项
我正在使用相当棒的 jQuery 多重选择插件, ASM select
这个插件是如此接近我的需求,我必须尝试修复我能找到的唯一一个错误。
在初始加载时,选择器检查是否有任何具有“selected”属性的元素并选择它们。这很好,除非没有任何东西具有“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);
我希望有人能解决这个问题。
蒂姆
I am using the rather fantastic jQuery multiple select plugin, ASM select
This plugin is so close to my needs I have to try and fix the one and only bug I can find.
On initial load, the selector checks for any elements that have the attribute "selected" and selects them. This is good, except when nothing has the attribute "selected" it chooses the first one.
How can I stop it from doing this? I don't want anything initially selected as 9/10 times it is going to be the wrong option.
I am no jQuery coder and have looked through the code and have found several references to building the first select item and have fiddled with them, but have not had any success.
I don't usually do this but seeing as I have absolutely no idea where to start, here is the code for the plugin.
/*
* 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);
I hope someone has a solution to this problem.
Tim
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看来这个插件没有错,而是操作符......我
未能指定
multiple
属性会导致 ASM select 简单地将选择框视为普通选择框,当然它总是有一个已选择选项。哦。
我想该睡觉了。
It seems that this plugin is not at fault but rather the operator... me
Failing to specify the
multiple
attribute causes ASM select to simply treat the select box as a normal select box which of course always has an option selected.Doh.
I think its time for bed.
将行 (): 替换
为以下内容:
此外,您还需要替换:
为:
注意:
希望它有帮助!
Replace lines ():
With the following:
In addition you need to replace:
With:
Note:
Hope it helps!