-
Notifications
You must be signed in to change notification settings - Fork 0
/
jquery.multiselects.js
154 lines (136 loc) · 6.04 KB
/
jquery.multiselects.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
* Multiple Selects - jQuery plugin for converting a multiple <select> into two, adding the ability to move items between the boxes.
* http://code.google.com/p/jqmultiselects/
*
* Copyright (c) 2007 Rob Desbois
* 2011 Yury Samsonov
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Version: 0.3
*
* CHANGELOG
*
* 0.3 (Yury Samsonov <[email protected]>)
*
* INCOMPATIBLE WITH PREVIOUS VERSION!!!
*
* [+] Sorting feature added.
* [+] "Move all" triggers available
* [+] One call for full element - both source and destination
* [-] Old options syntax unsupported.
* [ ] All tabs replaced with spaces.
* [ ] Unix-style linebreaks (\n)
*
* There's three new options:
* - autoSort: true|false - enable sorting feature, enabled by default
* - sortType: "key"|"value"|function, default - "value" (visible text in select)
* - sortDesc: true|false - sort in reverse order, disabled by default
*
* You can use your own sorting function, recieving 2 <option> as argument (not jQuery-wrapped).
* Example:
* ...
* sortType: function (a, b) { return a.value - b.value; },
* ...
*
* 0.2
* <option> elements can be automatically selected upon parent form submission
* plugin options now passed as an array
* all element identifiers now taken as jQuery selectors instead
* added beforeMove and afterMove callback functions
*
* 0.1
* initial release
*/
(function( $ ){
$.fn.multiSelect = function(dest, options) {
options = $.extend({
keepSelected: false, // true => keep moved items selected
autoSubmit: true, // true => select all child <option>s on parent form submit (if any)
// buttons
button_select: null, // selector of elements whose 'click' should move selected options
button_select_all: null, // selector of elements whose 'click' should remove selected options from dest
button_deselect: null, // selector of elements whose 'click' should move all options to dest
button_deselect_all: null, // selector of elements whose 'click' should remove all options from dest
// sorting options
autoSort: true, // true => sort child <option>s elements after move
sortType: "value", // "value" => sort by visible text,
// "key" => by <option>s "value" attr
// function(a,b) => your sorting function
sortDesc: false, // true => sort in reverse order
// callbacks
beforeMove: null, // before move callback function, if returns false, no item will be moved
afterMove: null // after move callback
}, options);
// for closures
var $source = this;
var $dest = $(dest);
// make form submission select child <option>s
if (options.autoSubmit)
this.parents("form").submit(function() { selectChildOptions($dest); });
// sort options in both <selects>
var sortOptions = function(elem, sortType, desc) {
var order = desc ? -1 : 1;
if (typeof sortType == "function") {
var sort = sortType;
} else {
if (sortType == "key") {
var sort = function(a, b) { return order * ((b.value < a.value) - (a.value < b.value)); }
} else {
var sort = function(a, b) { return order * (($(b).text() < $(a).text()) - ($(a).text() < $(b).text())); }
}
}
var options = $.makeArray($('option', elem).detach()).sort(sort);
$(elem).append(options);
}
// wrapper for sort function
var sortFunction = function(element) {
if (!options.autoSort) {
return;
}
sortOptions(element, options.sortType, options.sortDesc);
}
// initial sort
sortFunction($source);
sortFunction($dest);
// wrapper for move function
var moveFunction = function(from, to, action) {
moveOptions(from, to, action, options.beforeMove, options.afterMove, sortFunction);
};
var moveAll = function (from, to) {
if (options.beforeMove && !options.beforeMove(from, dest, 'all'))
return;
$('option', from).attr('selected', 'selected');
moveFunction(from, to);
sortFunction(dest);
options.afterMove && options.afterMove(from, dest, 'all');
};
// move elements from source to dest
$source.dblclick(function() { moveFunction($source, $dest, 'select'); });
if(options.button_select) $(options.button_select).click(function() { moveFunction($source, $dest, 'select'); });
if(options.button_select_all) $(options.button_select_all).click(function() { moveAll($source, $dest); });
// move elements from dest to source
$dest.dblclick(function() { moveFunction($dest, $source, 'deselect'); });
if(options.button_deselect) $(options.button_deselect).click(function() { moveFunction($dest, $source, 'deselect'); });
if(options.button_deselect_all) $(options.button_deselect_all).click(function() { moveAll($dest, $source); });
return this;
// moves the options between <select>
// 'action' param can be 'select', 'deselect' or 'all'
function moveOptions(from, to, action, beforeMove, afterMove, sortFunction) {
if (beforeMove && !beforeMove(from, to, action))
return;
$("option:selected", from).each(function() {
$(this).appendTo(to);
});
sortFunction(to);
afterMove && afterMove(from, to, action);
}
// selects all child options
function selectChildOptions($dest) {
$dest.children("option").each(function() {
this.selected = true;
});
}
};
})(jQuery);