/[projects]/misc/horsensspejder-web/jquery/jquery-picklist.js
ViewVC logotype

Annotation of /misc/horsensspejder-web/jquery/jquery-picklist.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2125 - (hide annotations) (download) (as text)
Wed Mar 12 19:30:05 2014 UTC (10 years, 3 months ago) by torben
File MIME type: application/javascript
File size: 15004 byte(s)
initial import
1 torben 2125 /**
2     * jQuery PickList Widget
3     *
4     * Copyright (c) 2012-2013 Jonathon Freeman <jonathon@awnry.com>
5     * Distributed under the terms of the MIT License.
6     *
7     * http://code.google.com/p/jquery-ui-picklist/
8     */
9     (function($)
10     {
11     $.widget("awnry.pickList",
12     {
13     widgetEventPrefix: "pickList_",
14    
15     options:
16     {
17     // Container classes
18     mainClass: "pickList",
19     listContainerClass: "pickList_listContainer",
20     sourceListContainerClass: "pickList_sourceListContainer",
21     controlsContainerClass: "pickList_controlsContainer",
22     targetListContainerClass: "pickList_targetListContainer",
23     listClass: "pickList_list",
24     sourceListClass: "pickList_sourceList",
25     targetListClass: "pickList_targetList",
26     clearClass: "pickList_clear",
27    
28     // List item classes
29     listItemClass: "pickList_listItem",
30     richListItemClass: "pickList_richListItem",
31     selectedListItemClass: "pickList_selectedListItem",
32    
33     // Control classes
34     addAllClass: "pickList_addAll",
35     addClass: "pickList_add",
36     removeAllClass: "pickList_removeAll",
37     removeClass: "pickList_remove",
38    
39     // Control labels
40     addAllLabel: "&gt;&gt;",
41     addLabel: "&gt;",
42     removeAllLabel: "&lt;&lt;",
43     removeLabel: "&lt;",
44    
45     // List labels
46     listLabelClass: "pickList_listLabel",
47     sourceListLabel: "Available",
48     sourceListLabelClass: "pickList_sourceListLabel",
49     targetListLabel: "Selected",
50     targetListLabelClass: "pickList_targetListLabel",
51    
52     // Sorting
53     sortItems: true,
54     sortAttribute: "label",
55    
56     // Name of custom value attribute for list items
57     listItemValueAttribute: "data-value",
58    
59     // Additional list items
60     items: []
61     },
62    
63     _create: function()
64     {
65     var self = this;
66    
67     self._buildPickList();
68     self._refresh();
69     },
70    
71     _buildPickList: function()
72     {
73     var self = this;
74    
75     self._trigger("beforeBuild");
76    
77     self.pickList = $("<div/>")
78     .hide()
79     .addClass(self.options.mainClass)
80     .insertAfter(self.element)
81     .append(self._buildSourceList())
82     .append(self._buildControls())
83     .append(self._buildTargetList())
84     .append( $("<div/>").addClass(self.options.clearClass) );
85    
86     self._populateLists();
87    
88     self.element.hide();
89     self.pickList.show();
90    
91     self._trigger("afterBuild");
92     },
93    
94     _buildSourceList: function()
95     {
96     var self = this;
97    
98     var container = $("<div/>")
99     .addClass(self.options.listContainerClass)
100     .addClass(self.options.sourceListContainerClass)
101     .css({
102     "-moz-user-select": "none",
103     "-webkit-user-select": "none",
104     "user-select": "none",
105     "-ms-user-select": "none"
106     })
107     .each(function()
108     {
109     this.onselectstart = function() { return false; };
110     });
111    
112     var label = $("<div/>")
113     .text(self.options.sourceListLabel)
114     .addClass(self.options.listLabelClass)
115     .addClass(self.options.sourceListLabelClass);
116    
117     self.sourceList = $("<ul/>")
118     .addClass(self.options.listClass)
119     .addClass(self.options.sourceListClass)
120     .delegate("li", "click", { pickList: self }, self._changeHandler);
121    
122     container
123     .append(label)
124     .append(self.sourceList);
125    
126     self.sourceList.delegate(".pickList_listItem", "dblclick", {pickList: self}, function(e)
127     {
128     var self = e.data.pickList;
129     self._addItems( self.sourceList.children(".ui-selected") );
130     });
131    
132     return container;
133     },
134    
135     _buildTargetList: function()
136     {
137     var self = this;
138    
139     var container = $("<div/>")
140     .addClass(self.options.listContainerClass)
141     .addClass(self.options.targetListContainerClass)
142     .css({
143     "-moz-user-select": "none",
144     "-webkit-user-select": "none",
145     "user-select": "none",
146     "-ms-user-select": "none"
147     })
148     .each(function()
149     {
150     this.onselectstart = function() { return false; };
151     });
152    
153     var label = $("<div/>")
154     .text(self.options.targetListLabel)
155     .addClass(self.options.listLabelClass)
156     .addClass(self.options.targetListLabelClass);
157    
158     self.targetList = $("<ul/>")
159     .addClass(self.options.listClass)
160     .addClass(self.options.targetListClass)
161     .delegate("li", "click", { pickList: self }, self._changeHandler);
162    
163     container
164     .append(label)
165     .append(self.targetList);
166    
167     self.targetList.delegate(".pickList_listItem", "dblclick", {pickList: self}, function(e)
168     {
169     var self = e.data.pickList;
170     self._removeItems( self.targetList.children(".ui-selected") );
171     });
172    
173     return container;
174     },
175    
176     _buildControls: function()
177     {
178     var self = this;
179    
180     self.controls = $("<div/>").addClass(self.options.controlsContainerClass);
181    
182     self.addAllButton = $("<button type='button'/>").click({pickList: self}, self._addAllHandler).html(self.options.addAllLabel).addClass(self.options.addAllClass);
183     self.addButton = $("<button type='button'/>").click({pickList: self}, self._addHandler).html(self.options.addLabel).addClass(self.options.addClass);
184     self.removeButton = $("<button type='button'/>").click({pickList: self}, self._removeHandler).html(self.options.removeLabel).addClass(self.options.removeClass);
185     self.removeAllButton = $("<button type='button'/>").click({pickList: self}, self._removeAllHandler).html(self.options.removeAllLabel).addClass(self.options.removeAllClass);
186    
187     self.controls
188     .append(self.addAllButton)
189     .append(self.addButton)
190     .append(self.removeButton)
191     .append(self.removeAllButton);
192    
193     return self.controls;
194     },
195    
196     _populateLists: function()
197     {
198     var self = this;
199    
200     self._trigger("beforePopulate");
201    
202     var sourceListItems = [];
203     var targetListItems = [];
204     var selectItems = self.element.children();
205    
206     selectItems.not(":selected").each(function()
207     {
208     sourceListItems.push( self._createDoppelganger(this) );
209     });
210    
211     selectItems.filter(":selected").each(function()
212     {
213     targetListItems.push( self._createDoppelganger(this) );
214     });
215    
216     self.sourceList.append(sourceListItems.join("\n"));
217     self.targetList.append(targetListItems.join("\n"));
218     self.insertItems(self.options.items);
219    
220     self._trigger("afterPopulate");
221     },
222    
223     _addItems: function(items)
224     {
225     var self = this;
226    
227     self._trigger("beforeAdd");
228    
229     self.targetList.append( self._removeSelections(items) );
230    
231     var itemIds = [];
232     items.each(function()
233     {
234     itemIds.push( self._getItemValue(this) );
235     });
236    
237     self.element.children().filter(function()
238     {
239     return $.inArray(this.value, itemIds) != -1;
240     }).attr("selected", "selected");
241    
242     self._refresh();
243    
244     self._trigger("afterAdd", null, { items: items });
245     self._trigger("onChange", null, { type: "add", items: items });
246     },
247    
248     _removeItems: function(items)
249     {
250     var self = this;
251    
252     self._trigger("beforeRemove");
253    
254     self.sourceList.append( self._removeSelections(items) );
255    
256     var itemIds = [];
257     items.each(function()
258     {
259     itemIds.push( self._getItemValue(this) );
260     });
261    
262     self.element.children().filter(function()
263     {
264     return $.inArray(this.value, itemIds) != -1;
265     }).removeAttr("selected");
266    
267     self._refresh();
268    
269     self._trigger("afterRemove", null, { items: items });
270     self._trigger("onChange", null, { type: "remove", items: items });
271     },
272    
273     _addAllHandler: function(e)
274     {
275     var self = e.data.pickList;
276    
277     self._trigger("beforeAddAll");
278    
279     var items = self.sourceList.children();
280     self.targetList.append( self._removeSelections(items) );
281    
282     self.element.children().not(":selected").attr("selected", "selected");
283    
284     self._refresh();
285    
286     self._trigger("afterAddAll", null, { items: items });
287     self._trigger("onChange", null, { type: "addAll", items: items });
288     },
289    
290     _addHandler: function(e)
291     {
292     var self = e.data.pickList;
293     self._addItems(self.sourceList.children(".ui-selected"));
294     },
295    
296     _removeHandler: function(e)
297     {
298     var self = e.data.pickList;
299     self._removeItems(self.targetList.children(".ui-selected"));
300     },
301    
302     _removeAllHandler: function(e)
303     {
304     var self = e.data.pickList;
305    
306     self._trigger("beforeRemoveAll");
307    
308     var items = self.targetList.children();
309     self.sourceList.append( self._removeSelections(items) );
310    
311     self.element.children().filter(":selected").removeAttr("selected");
312    
313     self._refresh();
314    
315     self._trigger("afterRemoveAll", null, { items: items });
316     self._trigger("onChange", null, { type: "removeAll", items: items });
317     },
318    
319     _refresh: function()
320     {
321     var self = this;
322    
323     self._trigger("beforeRefresh");
324    
325     self._refreshControls();
326    
327     // Sort the selection lists.
328     if(self.options.sortItems)
329     {
330     self._sortItems(self.sourceList, self.options);
331     self._sortItems(self.targetList, self.options);
332     }
333    
334     self._trigger("afterRefresh");
335     },
336    
337     _refreshControls: function()
338     {
339     var self = this;
340    
341     self._trigger("beforeRefreshControls");
342    
343     // Enable/disable the Add All button state.
344     if(self.sourceList.children().length)
345     {
346     self.addAllButton.removeAttr("disabled");
347     }
348     else
349     {
350     self.addAllButton.attr("disabled", "disabled");
351     }
352    
353     // Enable/disable the Remove All button state.
354     if(self.targetList.children().length)
355     {
356     self.removeAllButton.removeAttr("disabled");
357     }
358     else
359     {
360     self.removeAllButton.attr("disabled", "disabled");
361     }
362    
363     // Enable/disable the Add button state.
364     if(self.sourceList.children(".ui-selected").length)
365     {
366     self.addButton.removeAttr("disabled");
367     }
368     else
369     {
370     self.addButton.attr("disabled", "disabled");
371     }
372    
373     // Enable/disable the Remove button state.
374     if(self.targetList.children(".ui-selected").length)
375     {
376     self.removeButton.removeAttr("disabled");
377     }
378     else
379     {
380     self.removeButton.attr("disabled", "disabled");
381     }
382    
383     self._trigger("afterRefreshControls");
384     },
385    
386     _sortItems: function(list, options)
387     {
388     var items = new Array();
389    
390     list.children().each(function()
391     {
392     items.push( $(this) );
393     });
394    
395     items.sort(function(a, b)
396     {
397     if(a.attr(options.sortAttribute) > b.attr(options.sortAttribute))
398     {
399     return 1;
400     }
401     else if(a.attr(options.sortAttribute) == b.attr(options.sortAttribute))
402     {
403     return 0;
404     }
405     else
406     {
407     return -1;
408     }
409     });
410    
411     list.empty();
412    
413     for(var i = 0; i < items.length; i++)
414     {
415     list.append(items[i]);
416     }
417     },
418    
419     _changeHandler: function(e)
420     {
421     var self = e.data.pickList;
422    
423     if(e.ctrlKey)
424     {
425     if(self._isSelected( $(this) ))
426     {
427     self._removeSelection( $(this) );
428     }
429     else
430     {
431     self.lastSelectedItem = $(this);
432     self._addSelection( $(this) );
433     }
434     }
435     else if(e.shiftKey)
436     {
437     var current = self._getItemValue(this);
438     var last = self._getItemValue(self.lastSelectedItem);
439    
440     if($(this).index() < $(self.lastSelectedItem).index())
441     {
442     var temp = current;
443     current = last;
444     last = temp;
445     }
446    
447     var pastStart = false;
448     var beforeEnd = true;
449    
450     self._clearSelections( $(this).parent() );
451    
452     $(this).parent().children().each(function()
453     {
454     if(self._getItemValue(this) == last)
455     {
456     pastStart = true;
457     }
458    
459     if(pastStart && beforeEnd)
460     {
461     self._addSelection( $(this) );
462     }
463    
464     if(self._getItemValue(this) == current)
465     {
466     beforeEnd = false;
467     }
468    
469     });
470     }
471     else
472     {
473     self.lastSelectedItem = $(this);
474     self._clearSelections( $(this).parent() );
475     self._addSelection( $(this) );
476     }
477    
478     self._refreshControls();
479     },
480    
481     _isSelected: function(listItem)
482     {
483     return listItem.hasClass("ui-selected");
484     },
485    
486     _addSelection: function(listItem)
487     {
488     var self = this;
489    
490     return listItem
491     .addClass("ui-selected")
492     .addClass("ui-state-highlight")
493     .addClass(self.options.selectedListItemClass);
494     },
495    
496     _removeSelection: function(listItem)
497     {
498     var self = this;
499    
500     return listItem
501     .removeClass("ui-selected")
502     .removeClass("ui-state-highlight")
503     .removeClass(self.options.selectedListItemClass);
504     },
505    
506     _removeSelections: function(listItems)
507     {
508     var self = this;
509    
510     listItems.each(function()
511     {
512     $(this)
513     .removeClass("ui-selected")
514     .removeClass("ui-state-highlight")
515     .removeClass(self.options.selectedListItemClass);
516     });
517    
518     return listItems;
519     },
520    
521     _clearSelections: function(list)
522     {
523     var self = this;
524    
525     list.children().each(function()
526     {
527     self._removeSelection( $(this) );
528     });
529     },
530    
531     _setOption: function(key, value)
532     {
533     switch(key)
534     {
535     case "clear":
536     {
537     break;
538     }
539     }
540    
541     $.Widget.prototype._setOption.apply(this, arguments);
542     },
543    
544     destroy: function()
545     {
546     var self = this;
547    
548     self._trigger("onDestroy");
549    
550     self.pickList.remove();
551     self.element.show();
552    
553     $.Widget.prototype.destroy.call(self);
554     },
555    
556     insert: function(item)
557     {
558     var self = this;
559    
560     var list = item.selected ? self.targetList : self.sourceList;
561     var selectItem = self._createSelectItem(item);
562     var listItem = self._createListItem(item);
563    
564     self.element.append(selectItem);
565     list.append(listItem);
566    
567     self._trigger("onChange");
568    
569     self._refresh();
570     },
571    
572     insertItems: function(items)
573     {
574     var self = this;
575    
576     var selectItems = [];
577     var sourceItems = [];
578     var targetItems = [];
579    
580     $(items).each(function()
581     {
582     var selectItem = self._createSelectItem(this);
583     var listItem = self._createListItem(this);
584    
585     selectItems.push(selectItem);
586    
587     if(this.selected)
588     {
589     targetItems.push(listItem);
590     }
591     else
592     {
593     sourceItems.push(listItem);
594     }
595     });
596    
597     self.element.append(selectItems.join("\n"));
598     self.sourceList.append(sourceItems.join("\n"));
599     self.targetList.append(targetItems.join("\n"));
600    
601     self._trigger("onChange");
602    
603     self._refresh();
604     },
605    
606     _createSelectItem: function(item)
607     {
608     var selected = item.selected ? " selected='selected'" : "";
609     return "<option value='" + item.value + "'" + selected + ">" + item.label + "</option>";
610     },
611    
612     _createListItem: function(item)
613     {
614     var self = this;
615    
616     if(item.element != undefined)
617     {
618     var richItemHtml = item.element.clone().wrap("<div>").parent().html();
619     item.element.hide();
620     return "<li " + self.options.listItemValueAttribute + "='" + item.value + "' label='" + item.label + "' class='" + self.options.listItemClass + " " + self.options.richListItemClass + "'>" + richItemHtml + "</li>";
621     }
622    
623     return "<li " + self.options.listItemValueAttribute + "='" + item.value + "' label='" + item.label + "' class='" + self.options.listItemClass + "'>" + item.label + "</li>";
624     },
625    
626     _createDoppelganger: function(item)
627     {
628     var self = this;
629     return "<li " + self.options.listItemValueAttribute + "='" + $(item).val() + "' label='" + $(item).text() + "' class='" + self.options.listItemClass + "'>" + $(item).text() + "</li>";
630     },
631    
632     _getItemValue: function(item)
633     {
634     var self = this;
635     return $(item).attr(self.options.listItemValueAttribute);
636     }
637     });
638     }(jQuery));

  ViewVC Help
Powered by ViewVC 1.1.20