2013-03-21 20 views

回答

1

插件沒有這樣的屬性。不存在對所選最大選項的限制。爲了補充一點,我改變了一下代碼,通過自己添加限制。

代碼很長,我在很多方面都改變了它,所以現在很難(我甚至不記得我所做的所有更改)指向這裏。我如何做一個簡短的解釋是這樣的:

  • 一個增加了新的內部變量稱爲selectLimit,默認設置爲一個大數目。要取消限制,您應該將該值設置爲小於選擇列表中的總項目的值。
  • 之前選擇一個新項目我檢查我是否可以選擇更多項目(如果選定項目的計數器,加上已添加在右側面板中的項目豐富),選擇項目的情況下,否則我取消選擇。
  • 我只在左側面板上限制選擇 - 如果在右側面板中您有超過限制的項目,那麼從該面板中選擇時限制不會影響您。如果您動態填充選取器並且所選項目超出限制,則這很好。

完整的代碼 - 插件與限制是:

/** 
* 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:    "&gt;&gt;", 
      addLabel:     "&gt;", 
      removeAllLabel:    "&lt;&lt;", 
      removeLabel:    "&lt;", 

      // 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 
}); 

我希望能幫助別人。

1

jquery-ui-picklist有多個事件掛鉤,你可以綁定一個函數,我認爲最好的選擇取決於具體情況。 afterAdd最有可能是最好的選擇,所以你可以在達到限制後禁用添加按鈕。 onChange計算兩個方向的事件,如果限制數量,則應該使用afterRemove來計數清除。

這裏是列表。

https://code.google.com/p/jquery-ui-picklist/wiki/CallbackEvents#onChange

按鈕控制是與類「addClass」的普通的HTML按鈕控件。您可以切換或修改此類或防止默認。我相信默認情況下Jquery插件包含一個「全部添加」按鈕以及「添加」。如果您的可能添加量大於您的限制,則需要在beforePopulate事件掛鉤中禁用此功能。只需使用.hide()調用按鈕即可。並且如果添加按鈕再次變爲eligble show()

+0

如果我得到了beforeAdd事件,我該如何取消添加過程?爲了使問題更清楚:我應該在beforeAdd處理程序中添加哪些代碼來取消添加過程? – 2013-03-21 09:41:41

+0

我認爲afterAdd是要走的路。我將添加取消過程到我的答案 – 2013-03-21 09:50:55