我在我的項目中使用jquery-ui-picklist jquery插件,我想設置用戶可以選擇的項目的限制。jquery-ui-picklist:設置最大選定項目
- 如何設置可以選擇的最大物品限制?
- 如何禁用控件上的按鈕? - 萬一最大數量的項目被選中,我想禁用「添加」按鈕
謝謝。
我在我的項目中使用jquery-ui-picklist jquery插件,我想設置用戶可以選擇的項目的限制。jquery-ui-picklist:設置最大選定項目
謝謝。
插件沒有這樣的屬性。不存在對所選最大選項的限制。爲了補充一點,我改變了一下代碼,通過自己添加限制。
代碼很長,我在很多方面都改變了它,所以現在很難(我甚至不記得我所做的所有更改)指向這裏。我如何做一個簡短的解釋是這樣的:
完整的代碼 - 插件與限制是:
/**
* jQuery PickList Widget
*
* Copyright (c) 2012 Jonathon Freeman <[email protected]>
* Distributed under the terms of the MIT License.
*
* http://code.google.com/p/jquery-ui-picklist/
*/
(function($)
{
$.widget("awnry.pickList",
{
widgetEventPrefix: "pickList_",
options:
{
// Container classes
mainClass: "pickList",
listContainerClass: "pickList_listContainer",
sourceListContainerClass: "pickList_sourceListContainer",
controlsContainerClass: "pickList_controlsContainer",
targetListContainerClass: "pickList_targetListContainer",
listClass: "pickList_list",
sourceListClass: "pickList_sourceList",
targetListClass: "pickList_targetList",
clearClass: "pickList_clear",
// List item classes
listItemClass: "pickList_listItem",
richListItemClass: "pickList_richListItem",
selectedListItemClass: "pickList_selectedListItem",
// Control classes
addAllClass: "pickList_addAll",
addClass: "pickList_add",
removeAllClass: "pickList_removeAll",
removeClass: "pickList_remove",
// Control labels
addAllLabel: ">>",
addLabel: ">",
removeAllLabel: "<<",
removeLabel: "<",
// List labels
listLabelClass: "pickList_listLabel",
sourceListLabel: "Available",
sourceListLabelClass: "pickList_sourceListLabel",
targetListLabel: "Selected",
targetListLabelClass: "pickList_targetListLabel",
// Sorting
sortItems: true,
sortAttribute: "label",
// Name of custom value attribute for list items
listItemValueAttribute: "data-value",
// Additional list items
items: [],
selectLimit: 10000
},
_create: function()
{
var self = this;
self._buildPickList();
self._refresh();
},
_buildPickList: function()
{
var self = this;
self._trigger("beforeBuild");
self.pickList = $("<div/>")
.hide()
.addClass(self.options.mainClass)
.insertAfter(self.element)
.append(self._buildSourceList())
.append(self._buildControls())
.append(self._buildTargetList())
.append($("<div/>").addClass(self.options.clearClass));
self._populateLists();
self.element.hide();
self.pickList.show();
self._trigger("afterBuild");
},
_buildSourceList: function()
{
var self = this;
var container = $("<div/>")
.addClass(self.options.listContainerClass)
.addClass(self.options.sourceListContainerClass)
.css({
"-moz-user-select": "none",
"-webkit-user-select": "none",
"user-select": "none",
"-ms-user-select": "none"
})
.each(function()
{
this.onselectstart = function() { return false; };
});
var label = $("<div/>")
.text(self.options.sourceListLabel)
.addClass(self.options.listLabelClass)
.addClass(self.options.sourceListLabelClass);
self.sourceList = $("<ul/>")
.addClass(self.options.listClass)
.addClass(self.options.sourceListClass)
.delegate("li", "click", { pickList: self }, self._changeHandler);
container
.append(label)
.append(self.sourceList);
return container;
},
_buildTargetList: function()
{
var self = this;
var container = $("<div/>")
.addClass(self.options.listContainerClass)
.addClass(self.options.targetListContainerClass)
.css({
"-moz-user-select": "none",
"-webkit-user-select": "none",
"user-select": "none",
"-ms-user-select": "none"
})
.each(function()
{
this.onselectstart = function() { return false; };
});
var label = $("<div/>")
.text(self.options.targetListLabel)
.addClass(self.options.listLabelClass)
.addClass(self.options.targetListLabelClass);
self.targetList = $("<ul/>")
.addClass(self.options.listClass)
.addClass(self.options.targetListClass)
.delegate("li", "click", { pickList: self }, self._changeHandler);
container
.append(label)
.append(self.targetList);
return container;
},
_buildControls: function()
{
var self = this;
self.controls = $("<div/>").addClass(self.options.controlsContainerClass);
self.addAllButton = $("<button type='button'/>").click({pickList: self}, self._addAllHandler).html(self.options.addAllLabel).addClass(self.options.addAllClass);
self.addButton = $("<button type='button'/>").click({pickList: self}, self._addHandler).html(self.options.addLabel).addClass(self.options.addClass);
self.removeButton = $("<button type='button'/>").click({pickList: self}, self._removeHandler).html(self.options.removeLabel).addClass(self.options.removeClass);
self.removeAllButton = $("<button type='button'/>").click({pickList: self}, self._removeAllHandler).html(self.options.removeAllLabel).addClass(self.options.removeAllClass);
self.controls
.append(self.addAllButton)
.append(self.addButton)
.append(self.removeButton)
.append(self.removeAllButton);
return self.controls;
},
_populateLists: function()
{
var self = this;
self._trigger("beforePopulate");
var sourceListItems = [];
var targetListItems = [];
var selectItems = self.element.children();
selectItems.not(":selected").each(function()
{
sourceListItems.push(self._createDoppelganger(this));
});
selectItems.filter(":selected").each(function()
{
targetListItems.push(self._createDoppelganger(this));
});
self.sourceList.append(sourceListItems.join("\n"));
self.targetList.append(targetListItems.join("\n"));
self.insertItems(self.options.items);
self._trigger("afterPopulate");
},
_addAllHandler: function(e)
{
var self = e.data.pickList;
self._trigger("beforeAddAll");
var items = self.sourceList.children();
self.targetList.append(self._removeSelections(items));
self.element.children().not(":selected").attr("selected", "selected");
self._refresh();
self._trigger("afterAddAll", null, { items: items });
self._trigger("onChange", null, { type: "addAll", items: items });
},
_addHandler: function(e)
{
var self = e.data.pickList;
self._trigger("beforeAdd");
var items = self.sourceList.children(".ui-selected");
self.targetList.append(self._removeSelections(items));
var itemIds = [];
items.each(function()
{
itemIds.push(self._getItemValue(this));
});
self.element.children().filter(function()
{
return $.inArray(this.value, itemIds) != -1;
}).attr("selected", "selected");
self._refresh();
self._trigger("afterAdd", null, { items: items });
self._trigger("onChange", null, { type: "add", items: items });
},
_removeHandler: function(e)
{
var self = e.data.pickList;
self._trigger("beforeRemove");
var items = self.targetList.children(".ui-selected");
self.sourceList.append(self._removeSelections(items));
var itemIds = [];
items.each(function()
{
itemIds.push(self._getItemValue(this));
});
self.element.children().filter(function()
{
return $.inArray(this.value, itemIds) != -1;
}).removeAttr("selected");
self._refresh();
self._trigger("afterRemove", null, { items: items });
self._trigger("onChange", null, { type: "remove", items: items });
},
_removeAllHandler: function(e)
{
var self = e.data.pickList;
self._trigger("beforeRemoveAll");
var items = self.targetList.children();
self.sourceList.append(self._removeSelections(items));
self.element.children().filter(":selected").removeAttr("selected");
self._refresh();
self._trigger("afterRemoveAll", null, { items: items });
self._trigger("onChange", null, { type: "removeAll", items: items });
},
_refresh: function()
{
var self = this;
self._trigger("beforeRefresh");
self._refreshControls();
// Sort the selection lists.
if(self.options.sortItems)
{
self._sortItems(self.sourceList, self.options);
self._sortItems(self.targetList, self.options);
}
self._trigger("afterRefresh");
},
_refreshControls: function()
{
var self = this;
var addBtnEnabled = (self.targetList.children().length < self.options.selectLimit);
self._trigger("beforeRefreshControls");
// Enable/disable the Add All button state.
if(self.sourceList.children().length)
{
self.addAllButton.removeAttr("disabled");
}
else
{
self.addAllButton.attr("disabled", "disabled");
}
// Enable/disable the Remove All button state.
if(self.targetList.children().length)
{
self.removeAllButton.removeAttr("disabled");
}
else
{
self.removeAllButton.attr("disabled", "disabled");
}
// Enable/disable the Add button state.
if(self.sourceList.children(".ui-selected").length && addBtnEnabled)
{
self.addButton.removeAttr("disabled");
}
else
{
self.addButton.attr("disabled", "disabled");
}
// Enable/disable the Remove button state.
if(self.targetList.children(".ui-selected").length)
{
self.removeButton.removeAttr("disabled");
}
else
{
self.removeButton.attr("disabled", "disabled");
}
self._trigger("afterRefreshControls");
},
_sortItems: function(list, options)
{
var items = new Array();
list.children().each(function()
{
items.push($(this));
});
items.sort(function(a, b)
{
if(a.attr(options.sortAttribute) > b.attr(options.sortAttribute))
{
return 1;
}
else if(a.attr(options.sortAttribute) == b.attr(options.sortAttribute))
{
return 0;
}
else
{
return -1;
}
});
list.empty();
for(var i = 0; i < items.length; i++)
{
list.append(items[i]);
}
},
_changeHandler: function(e)
{
var self = e.data.pickList;
var isClickOnSourcePanel = this.parentNode.attributes["class"].nodeValue.indexOf("pickList_sourceList") >= 0;
var selectedItems = self.sourceList.children(".ui-selected").length;
var leftToSelect = self.options.selectLimit - self.targetList.children().length - selectedItems - 1;
var canSelectMore = isClickOnSourcePanel && leftToSelect >= 0;
if(e.ctrlKey)
{
if(self._isSelected($(this)))
{
self._removeSelection($(this));
}
else
{
if(canSelectMore){
self.lastSelectedItem = $(this);
self._addSelection($(this));
}
else if(!isClickOnSourcePanel){ //allow to select/deselect without restrictions on right panel.
self.lastSelectedItem = $(this);
self._addSelection($(this));
}
}
}
//don't need to select with shift. For a small amount of selectale items
// else if(e.shiftKey)
// {
// var current = self._getItemValue(this);
// var last = self._getItemValue(self.lastSelectedItem);
//
// if($(this).index() < $(self.lastSelectedItem).index())
// {
// var temp = current;
// current = last;
// last = temp;
// }
//
// var pastStart = false;
// var beforeEnd = true;
//
// self._clearSelections($(this).parent());
//
// $(this).parent().children().each(function()
// {
// if(self._getItemValue(this) == last)
// {
// pastStart = true;
// }
//
// if(pastStart && beforeEnd)
// {
// self._addSelection($(this));
// }
//
// if(self._getItemValue(this) == current)
// {
// beforeEnd = false;
// }
//
// });
// }
else
{
if(canSelectMore){
self.lastSelectedItem = $(this);
self._clearSelections($(this).parent());
self._addSelection($(this));
}
else if(!isClickOnSourcePanel){
self.lastSelectedItem = $(this);
self._clearSelections($(this).parent());
self._addSelection($(this));
}
}
self._refreshControls();
},
_isSelected: function(listItem)
{
return listItem.hasClass("ui-selected");
},
_addSelection: function(listItem)
{
var self = this;
return listItem
.addClass("ui-selected")
.addClass("ui-state-highlight")
.addClass(self.options.selectedListItemClass);
},
_removeSelection: function(listItem)
{
var self = this;
return listItem
.removeClass("ui-selected")
.removeClass("ui-state-highlight")
.removeClass(self.options.selectedListItemClass);
},
_removeSelections: function(listItems)
{
var self = this;
listItems.each(function()
{
$(this)
.removeClass("ui-selected")
.removeClass("ui-state-highlight")
.removeClass(self.options.selectedListItemClass);
});
return listItems;
},
_clearSelections: function(list)
{
var self = this;
list.children().each(function()
{
self._removeSelection($(this));
});
},
_setOption: function(key, value)
{
switch(key)
{
case "clear":
{
break;
}
}
$.Widget.prototype._setOption.apply(this, arguments);
},
destroy: function()
{
var self = this;
self._trigger("onDestroy");
self.pickList.remove();
self.element.show();
$.Widget.prototype.destroy.call(self);
},
insert: function(item)
{
var self = this;
var list = item.selected ? self.targetList : self.sourceList;
var selectItem = self._createSelectItem(item);
var listItem = self._createListItem(item);
self.element.append(selectItem);
list.append(listItem);
self._trigger("onChange");
self._refresh();
},
insertItems: function(items)
{
var self = this;
var selectItems = [];
var sourceItems = [];
var targetItems = [];
$(items).each(function()
{
var selectItem = self._createSelectItem(this);
var listItem = self._createListItem(this);
selectItems.push(selectItem);
if(this.selected)
{
targetItems.push(listItem);
}
else
{
sourceItems.push(listItem);
}
});
self.element.append(selectItems.join("\n"));
self.sourceList.append(sourceItems.join("\n"));
self.targetList.append(targetItems.join("\n"));
self._trigger("onChange");
self._refresh();
},
_createSelectItem: function(item)
{
var selected = item.selected ? " selected='selected'" : "";
return "<option value='" + item.value + "'" + selected + ">" + item.label + "</option>";
},
_createListItem: function(item)
{
var self = this;
if(item.element != undefined)
{
var richItemHtml = item.element.clone().wrap("<div>").parent().html();
item.element.hide();
return "<li " + self.options.listItemValueAttribute + "='" + item.value + "' label='" + item.label + "' class='" + self.options.listItemClass + " " + self.options.richListItemClass + "'>" + richItemHtml + "</li>";
}
return "<li " + self.options.listItemValueAttribute + "='" + item.value + "' label='" + item.label + "' class='" + self.options.listItemClass + "'>" + item.label + "</li>";
},
_createDoppelganger: function(item)
{
var self = this;
return "<li " + self.options.listItemValueAttribute + "='" + $(item).val() + "' label='" + $(item).text() + "' class='" + self.options.listItemClass + "'>" + $(item).text() + "</li>";
},
_getItemValue: function(item)
{
var self = this;
return $(item).attr(self.options.listItemValueAttribute);
},
selectedAssets:function(){
var self = this;
var selectedItems = [];
self.targetList.children().each(function(){
var a = {};
a.id = $(this).attr(self.options.listItemValueAttribute);
a.name = $(this).attr("label");
selectedItems.push(a);
});
return selectedItems;
}
});
}(jQuery));
現在,使用它,你只寫:
$("#pckAssets").pickList({
selectLimit : 5
});
我希望能幫助別人。
jquery-ui-picklist有多個事件掛鉤,你可以綁定一個函數,我認爲最好的選擇取決於具體情況。 afterAdd最有可能是最好的選擇,所以你可以在達到限制後禁用添加按鈕。 onChange計算兩個方向的事件,如果限制數量,則應該使用afterRemove來計數清除。
這裏是列表。
https://code.google.com/p/jquery-ui-picklist/wiki/CallbackEvents#onChange
按鈕控制是與類「addClass」的普通的HTML按鈕控件。您可以切換或修改此類或防止默認。我相信默認情況下Jquery插件包含一個「全部添加」按鈕以及「添加」。如果您的可能添加量大於您的限制,則需要在beforePopulate事件掛鉤中禁用此功能。只需使用.hide()調用按鈕即可。並且如果添加按鈕再次變爲eligble show()
如果我得到了beforeAdd事件,我該如何取消添加過程?爲了使問題更清楚:我應該在beforeAdd處理程序中添加哪些代碼來取消添加過程? – 2013-03-21 09:41:41
我認爲afterAdd是要走的路。我將添加取消過程到我的答案 – 2013-03-21 09:50:55