-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathjquery.comboselect.js
212 lines (183 loc) · 8.59 KB
/
jquery.comboselect.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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// jQuery comboselect plugin
//
// version 2.0.0
// Versions 2+ represent a reworking of the plugin. See Jason Huck's site for the original
// I used spring board. http://devblog.jasonhuck.com/
//
// This reworking add efficiency and some options and a bug fix for the invalid markup.
// Its also done with jQuery 1.4 in mind.
// Sorting is removed for the time being.
// ------------------------------------------------------------------------------------
//
// Transforms a single select element into a pair of multi-selects
// with controls to move items left to right and vice versa.
// items are submitted by the original form element. Double-clicking
// moves an item from one side to the other.
//
//
// Usage: $('#myselect').comboselect({
// sort: 'both', // sort which sides? 'none'|'left'|'right'|'both'
// addremall : true, // include the add/remove all buttons
// add_allbtn: ' >> ', // label for the "add all" button
// rem_allbtn: ' << ', // label for the "remove all" button
// addbtn: ' > ',// text of the "add" button
// rembtn: ' < ',// text of the "remove" button
// cs_container: 'div', // html tag to contain both comboselects
// btn_container: 'div' // html tag to contain the comboselect buttons
// addbtn: [string,default:' > '], // label for the "add" button
// rembtn: [string,default:' < ']// label for the "remove" button
// });
// To set for legeacy compatibility, define the following after you include the plugin, but before you 'wire' it to anything:
// jQuery.fn.comboselect.defaults = {
// sort: 'both',
// addremall : false,
// addbtn: ' > ',
// rembtn: ' < ',
// cs_container: 'fieldset',
// btn_container: 'fieldset'
// };
// This method can be used for any defaults you prefer, so you do not have to set options on each use of the comboselect.
//
//
// Version History
// 2.0.0 Reworking release, no sorting
// * Removed selso dependency
// * Added ability to set global options
// * Added add/remove all button and text options
// * Changed fieldsets to divs for select and button containers
// * Added option to specify container element for generated selects
// * Added option to specify container element for generated buttons
//
// 1.0.2 Now works correctly if the form is not the immediate parent of the select.
// Clears originally selected options before updating with user's new selections on submit.
// Correctly transforms selects whose options were added dynamically.
// 1.0.1 Correctly transforms inputs which already had options selected.
// 1.0.0 Initial release.
(function($){
jQuery.fn.comboselect = function(settings){
settings = jQuery.extend({
sort: 'both', // sort which sides? 'none'|'left'|'right'|'both'
addremall : true, // include the add/remove all buttons
add_allbtn: ' >> ', // label for the "add all" button
rem_allbtn: ' << ', // label for the "remove all" button
addbtn: ' > ',// text of the "add" button
rembtn: ' < ',// text of the "remove" button
cs_container: 'div', // html tag to contain both comboselects
btn_container: 'div' // html tag to contain the comboselect buttons
}, jQuery.fn.comboselect.defaults, settings);
this.each(function(){
$this = $(this);
// the id of the original element
var selectID = this.id;
// ids for the left and right sides the combo box
var leftID = selectID + '_left';
var rightID = selectID + '_right';
// ids for add and remove buttons
var addID = selectID + "_add";
var removeID = selectID + "_remove";
// place to store markup for the combo box
var combo = '';
// copy of selected and not selected options from original select
var selectedOptions = $this.find('option:selected').clone();
var unSelectedOptions = $this.find('option:not(:selected)').clone();
// build the combo box
combo += '<' + settings.cs_container + ' class="comboselect">';
combo += '<select id="' + leftID + '" name="' + leftID + '" class="csleft" multiple="multiple">';
combo += '</select>';
combo += '<' + settings.btn_container + ' class="cs-buttons">';
combo += '<input type="button" class="csadd" id="' + addID + '" value="' + settings.addbtn + '" />';
if(settings.addremall){
combo += '<input type="button" class="csadd" id="' + addID + '_all" value="' + settings.add_allbtn + '" />';
combo += '<input type="button" class="csremove" id="' + removeID + '_all" value="' + settings.rem_allbtn + '" />';
}
combo += '<input type="button" class="csremove" id="' + removeID + '" value="' + settings.rembtn + '" />';
combo += '</' + settings.btn_container + '>';
combo += '<select id="' + rightID + '" name="' + rightID + '" class="csright" multiple="multiple">';
combo += '</select>';
combo += '</' + settings.cs_container + '>';
// hide the original element and
// add the combo box after it
$this.hide().after(combo);
// find the combo box in the DOM and append
// a copy of the unselected options
// element to the left side
$('#' + leftID).append(unSelectedOptions);
// and selected on the right
$('#' + rightID).append(selectedOptions);
var leftSelect = $("#" + leftID);
var rightSelect = $("#"+ rightID);
var originalSelect = $("#" + selectID)
// bind add and remove buttons
$("#" + addID).click(function(){
addSelections(leftSelect, rightSelect, originalSelect);
sortSelects(leftSelect, rightSelect, originalSelect, 'right');
});
$("#" + removeID).click(function(){
removeSelections(leftSelect, rightSelect, originalSelect);
sortSelects(leftSelect, rightSelect, originalSelect, 'left');
});
// bind add and remove all buttons
$("#" + addID + "_all").click(function(){
addAllSelections(leftSelect, rightSelect, originalSelect);
sortSelects(leftSelect, rightSelect, originalSelect, 'right');
});
$("#" + removeID + "_all").click(function(){
removeAllSelections(leftSelect, rightSelect, originalSelect);
sortSelects(leftSelect, rightSelect, originalSelect,'left');
});
// bind double clicking options
$("#" + leftID).dblclick(function(){
addSelections(leftSelect, rightSelect, originalSelect);
sortSelects(leftSelect, rightSelect, originalSelect,'right');
});
$("#" + rightID).dblclick(function(){
removeSelections(leftSelect, rightSelect, originalSelect);
sortSelects(leftSelect, rightSelect, originalSelect,'left');
});
});
function addSelections(left, right, original){
var selected = left.find(":selected");
right.append(selected);
selected.each(function(){
original.find('option[value="' + $(this).val() + '"]').attr('selected','selected');
});
}
function removeSelections(left, right, original){
var selected = right.find(":selected");
left.append(selected);
selected.each(function(){
original.find('option[value="' + $(this).val() + '"]').removeAttr('selected');
});
}
function addAllSelections(left, right, original){
right.append(left.find('option'));
original.find('option').attr('selected','selected');
}
function removeAllSelections(left, right, original){
left.append(right.find('option'));
original.find('option').removeAttr('selected');
}
function sortSelects(left, right, original, side){
var order = jQuery.map(original.find('option'), function(option){
var $option = $(option);
return $option.attr("value") + $option.text()
});
if((settings.sort == 'both' || settings.sort == 'right') && side == 'right' ){
sortSelect(right, order);
}
if((settings.sort == 'both' || settings.sort == 'left') && side == 'left' ){
sortSelect(left, order);
}
}
function sortSelect(sortable, order){
var sorted = sortable.find('option').sort(function(a,b){
var $a = $(a); var $b = $(b);
cA = jQuery.inArray($a.attr("value") + $a.text(), order);
cB = jQuery.inArray($b.attr("value") + $b.text(), order);
return (cA < cB) ? -1 : (cA > cB) ? 1 : 0;
});
sortable.append(sorted);
}
return this;
};
})(jQuery);