1 | /*
|
---|
2 | *
|
---|
3 | * Copyright (c) 2006-2009 Sam Collett (http://www.texotela.co.uk)
|
---|
4 | * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
---|
5 | * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
|
---|
6 | *
|
---|
7 | * Version 2.2.4
|
---|
8 | * Demo: http://www.texotela.co.uk/code/jquery/select/
|
---|
9 | *
|
---|
10 | * $LastChangedDate: 2009-02-08 00:28:12 +0000 (Sun, 08 Feb 2009) $
|
---|
11 | * $Rev: 6185 $
|
---|
12 | *
|
---|
13 | */
|
---|
14 |
|
---|
15 | ;(function($) {
|
---|
16 |
|
---|
17 | /**
|
---|
18 | * Adds (single/multiple) options to a select box (or series of select boxes)
|
---|
19 | *
|
---|
20 | * @name addOption
|
---|
21 | * @author Sam Collett (http://www.texotela.co.uk)
|
---|
22 | * @type jQuery
|
---|
23 | * @example $("#myselect").addOption("Value", "Text"); // add single value (will be selected)
|
---|
24 | * @example $("#myselect").addOption("Value 2", "Text 2", false); // add single value (won't be selected)
|
---|
25 | * @example $("#myselect").addOption({"foo":"bar","bar":"baz"}, false); // add multiple values, but don't select
|
---|
26 | *
|
---|
27 | */
|
---|
28 | $.fn.addOption = function()
|
---|
29 | {
|
---|
30 | var add = function(el, v, t, sO)
|
---|
31 | {
|
---|
32 | var option = document.createElement("option");
|
---|
33 | option.value = v, option.text = t;
|
---|
34 | // get options
|
---|
35 | var o = el.options;
|
---|
36 | // get number of options
|
---|
37 | var oL = o.length;
|
---|
38 | if(!el.cache)
|
---|
39 | {
|
---|
40 | el.cache = {};
|
---|
41 | // loop through existing options, adding to cache
|
---|
42 | for(var i = 0; i < oL; i++)
|
---|
43 | {
|
---|
44 | el.cache[o[i].value] = i;
|
---|
45 | }
|
---|
46 | }
|
---|
47 | // add to cache if it isn't already
|
---|
48 | if(typeof el.cache[v] == "undefined") el.cache[v] = oL;
|
---|
49 | el.options[el.cache[v]] = option;
|
---|
50 | if(sO)
|
---|
51 | {
|
---|
52 | option.selected = true;
|
---|
53 | }
|
---|
54 | };
|
---|
55 |
|
---|
56 | var a = arguments;
|
---|
57 | if(a.length == 0) return this;
|
---|
58 | // select option when added? default is true
|
---|
59 | var sO = true;
|
---|
60 | // multiple items
|
---|
61 | var m = false;
|
---|
62 | // other variables
|
---|
63 | var items, v, t;
|
---|
64 | if(typeof(a[0]) == "object")
|
---|
65 | {
|
---|
66 | m = true;
|
---|
67 | items = a[0];
|
---|
68 | }
|
---|
69 | if(a.length >= 2)
|
---|
70 | {
|
---|
71 | if(typeof(a[1]) == "boolean") sO = a[1];
|
---|
72 | else if(typeof(a[2]) == "boolean") sO = a[2];
|
---|
73 | if(!m)
|
---|
74 | {
|
---|
75 | v = a[0];
|
---|
76 | t = a[1];
|
---|
77 | }
|
---|
78 | }
|
---|
79 | this.each(
|
---|
80 | function()
|
---|
81 | {
|
---|
82 | if(this.nodeName.toLowerCase() != "select") return;
|
---|
83 | if(m)
|
---|
84 | {
|
---|
85 | for(var item in items)
|
---|
86 | {
|
---|
87 | add(this, item, items[item], sO);
|
---|
88 | }
|
---|
89 | }
|
---|
90 | else
|
---|
91 | {
|
---|
92 | add(this, v, t, sO);
|
---|
93 | }
|
---|
94 | }
|
---|
95 | );
|
---|
96 | return this;
|
---|
97 | };
|
---|
98 |
|
---|
99 | /**
|
---|
100 | * Add options via ajax
|
---|
101 | *
|
---|
102 | * @name ajaxAddOption
|
---|
103 | * @author Sam Collett (http://www.texotela.co.uk)
|
---|
104 | * @type jQuery
|
---|
105 | * @param String url Page to get options from (must be valid JSON)
|
---|
106 | * @param Object params (optional) Any parameters to send with the request
|
---|
107 | * @param Boolean select (optional) Select the added options, default true
|
---|
108 | * @param Function fn (optional) Call this function with the select object as param after completion
|
---|
109 | * @param Array args (optional) Array with params to pass to the function afterwards
|
---|
110 | * @example $("#myselect").ajaxAddOption("myoptions.php");
|
---|
111 | * @example $("#myselect").ajaxAddOption("myoptions.php", {"code" : "007"});
|
---|
112 | * @example $("#myselect").ajaxAddOption("myoptions.php", {"code" : "007"}, false, sortoptions, [{"dir": "desc"}]);
|
---|
113 | *
|
---|
114 | */
|
---|
115 | $.fn.ajaxAddOption = function(url, params, select, fn, args)
|
---|
116 | {
|
---|
117 | if(typeof(url) != "string") return this;
|
---|
118 | if(typeof(params) != "object") params = {};
|
---|
119 | if(typeof(select) != "boolean") select = true;
|
---|
120 | this.each(
|
---|
121 | function()
|
---|
122 | {
|
---|
123 | var el = this;
|
---|
124 | $.getJSON(url,
|
---|
125 | params,
|
---|
126 | function(r)
|
---|
127 | {
|
---|
128 | $(el).addOption(r, select);
|
---|
129 | if(typeof fn == "function")
|
---|
130 | {
|
---|
131 | if(typeof args == "object")
|
---|
132 | {
|
---|
133 | fn.apply(el, args);
|
---|
134 | }
|
---|
135 | else
|
---|
136 | {
|
---|
137 | fn.call(el);
|
---|
138 | }
|
---|
139 | }
|
---|
140 | }
|
---|
141 | );
|
---|
142 | }
|
---|
143 | );
|
---|
144 | return this;
|
---|
145 | };
|
---|
146 |
|
---|
147 | /**
|
---|
148 | * Removes an option (by value or index) from a select box (or series of select boxes)
|
---|
149 | *
|
---|
150 | * @name removeOption
|
---|
151 | * @author Sam Collett (http://www.texotela.co.uk)
|
---|
152 | * @type jQuery
|
---|
153 | * @param String|RegExp|Number what Option to remove
|
---|
154 | * @param Boolean selectedOnly (optional) Remove only if it has been selected (default false)
|
---|
155 | * @example $("#myselect").removeOption("Value"); // remove by value
|
---|
156 | * @example $("#myselect").removeOption(/^val/i); // remove options with a value starting with 'val'
|
---|
157 | * @example $("#myselect").removeOption(/./); // remove all options
|
---|
158 | * @example $("#myselect").removeOption(/./, true); // remove all options that have been selected
|
---|
159 | * @example $("#myselect").removeOption(0); // remove by index
|
---|
160 | * @example $("#myselect").removeOption(["myselect_1","myselect_2"]); // values contained in passed array
|
---|
161 | *
|
---|
162 | */
|
---|
163 | $.fn.removeOption = function()
|
---|
164 | {
|
---|
165 | var a = arguments;
|
---|
166 | if(a.length == 0) return this;
|
---|
167 | var ta = typeof(a[0]);
|
---|
168 | var v, index;
|
---|
169 | // has to be a string or regular expression (object in IE, function in Firefox)
|
---|
170 | if(ta == "string" || ta == "object" || ta == "function" )
|
---|
171 | {
|
---|
172 | v = a[0];
|
---|
173 | // if an array, remove items
|
---|
174 | if(v.constructor == Array)
|
---|
175 | {
|
---|
176 | var l = v.length;
|
---|
177 | for(var i = 0; i<l; i++)
|
---|
178 | {
|
---|
179 | this.removeOption(v[i], a[1]);
|
---|
180 | }
|
---|
181 | return this;
|
---|
182 | }
|
---|
183 | }
|
---|
184 | else if(ta == "number") index = a[0];
|
---|
185 | else return this;
|
---|
186 | this.each(
|
---|
187 | function()
|
---|
188 | {
|
---|
189 | if(this.nodeName.toLowerCase() != "select") return;
|
---|
190 | // clear cache
|
---|
191 | if(this.cache) this.cache = null;
|
---|
192 | // does the option need to be removed?
|
---|
193 | var remove = false;
|
---|
194 | // get options
|
---|
195 | var o = this.options;
|
---|
196 | if(!!v)
|
---|
197 | {
|
---|
198 | // get number of options
|
---|
199 | var oL = o.length;
|
---|
200 | for(var i=oL-1; i>=0; i--)
|
---|
201 | {
|
---|
202 | if(v.constructor == RegExp)
|
---|
203 | {
|
---|
204 | if(o[i].value.match(v))
|
---|
205 | {
|
---|
206 | remove = true;
|
---|
207 | }
|
---|
208 | }
|
---|
209 | else if(o[i].value == v)
|
---|
210 | {
|
---|
211 | remove = true;
|
---|
212 | }
|
---|
213 | // if the option is only to be removed if selected
|
---|
214 | if(remove && a[1] === true) remove = o[i].selected;
|
---|
215 | if(remove)
|
---|
216 | {
|
---|
217 | o[i] = null;
|
---|
218 | }
|
---|
219 | remove = false;
|
---|
220 | }
|
---|
221 | }
|
---|
222 | else
|
---|
223 | {
|
---|
224 | // only remove if selected?
|
---|
225 | if(a[1] === true)
|
---|
226 | {
|
---|
227 | remove = o[index].selected;
|
---|
228 | }
|
---|
229 | else
|
---|
230 | {
|
---|
231 | remove = true;
|
---|
232 | }
|
---|
233 | if(remove)
|
---|
234 | {
|
---|
235 | this.remove(index);
|
---|
236 | }
|
---|
237 | }
|
---|
238 | }
|
---|
239 | );
|
---|
240 | return this;
|
---|
241 | };
|
---|
242 |
|
---|
243 | /**
|
---|
244 | * Sort options (ascending or descending) in a select box (or series of select boxes)
|
---|
245 | *
|
---|
246 | * @name sortOptions
|
---|
247 | * @author Sam Collett (http://www.texotela.co.uk)
|
---|
248 | * @type jQuery
|
---|
249 | * @param Boolean ascending (optional) Sort ascending (true/undefined), or descending (false)
|
---|
250 | * @example // ascending
|
---|
251 | * $("#myselect").sortOptions(); // or $("#myselect").sortOptions(true);
|
---|
252 | * @example // descending
|
---|
253 | * $("#myselect").sortOptions(false);
|
---|
254 | *
|
---|
255 | */
|
---|
256 | $.fn.sortOptions = function(ascending)
|
---|
257 | {
|
---|
258 | // get selected values first
|
---|
259 | var sel = $(this).selectedValues();
|
---|
260 | var a = typeof(ascending) == "undefined" ? true : !!ascending;
|
---|
261 | this.each(
|
---|
262 | function()
|
---|
263 | {
|
---|
264 | if(this.nodeName.toLowerCase() != "select") return;
|
---|
265 | // get options
|
---|
266 | var o = this.options;
|
---|
267 | // get number of options
|
---|
268 | var oL = o.length;
|
---|
269 | // create an array for sorting
|
---|
270 | var sA = [];
|
---|
271 | // loop through options, adding to sort array
|
---|
272 | for(var i = 0; i<oL; i++)
|
---|
273 | {
|
---|
274 | sA[i] = {
|
---|
275 | v: o[i].value,
|
---|
276 | t: o[i].text
|
---|
277 | }
|
---|
278 | }
|
---|
279 | // sort items in array
|
---|
280 | sA.sort(
|
---|
281 | function(o1, o2)
|
---|
282 | {
|
---|
283 | // option text is made lowercase for case insensitive sorting
|
---|
284 | o1t = o1.t.toLowerCase(), o2t = o2.t.toLowerCase();
|
---|
285 | // if options are the same, no sorting is needed
|
---|
286 | if(o1t == o2t) return 0;
|
---|
287 | if(a)
|
---|
288 | {
|
---|
289 | return o1t < o2t ? -1 : 1;
|
---|
290 | }
|
---|
291 | else
|
---|
292 | {
|
---|
293 | return o1t > o2t ? -1 : 1;
|
---|
294 | }
|
---|
295 | }
|
---|
296 | );
|
---|
297 | // change the options to match the sort array
|
---|
298 | for(var i = 0; i<oL; i++)
|
---|
299 | {
|
---|
300 | o[i].text = sA[i].t;
|
---|
301 | o[i].value = sA[i].v;
|
---|
302 | }
|
---|
303 | }
|
---|
304 | ).selectOptions(sel, true); // select values, clearing existing ones
|
---|
305 | return this;
|
---|
306 | };
|
---|
307 | /**
|
---|
308 | * Selects an option by value
|
---|
309 | *
|
---|
310 | * @name selectOptions
|
---|
311 | * @author Mathias Bank (http://www.mathias-bank.de), original function
|
---|
312 | * @author Sam Collett (http://www.texotela.co.uk), addition of regular expression matching
|
---|
313 | * @type jQuery
|
---|
314 | * @param String|RegExp|Array value Which options should be selected
|
---|
315 | * can be a string or regular expression, or an array of strings / regular expressions
|
---|
316 | * @param Boolean clear Clear existing selected options, default false
|
---|
317 | * @example $("#myselect").selectOptions("val1"); // with the value 'val1'
|
---|
318 | * @example $("#myselect").selectOptions(["val1","val2","val3"]); // with the values 'val1' 'val2' 'val3'
|
---|
319 | * @example $("#myselect").selectOptions(/^val/i); // with the value starting with 'val', case insensitive
|
---|
320 | *
|
---|
321 | */
|
---|
322 | $.fn.selectOptions = function(value, clear)
|
---|
323 | {
|
---|
324 | var v = value;
|
---|
325 | var vT = typeof(value);
|
---|
326 | // handle arrays
|
---|
327 | if(vT == "object" && v.constructor == Array)
|
---|
328 | {
|
---|
329 | var $this = this;
|
---|
330 | $.each(v, function()
|
---|
331 | {
|
---|
332 | $this.selectOptions(this, clear);
|
---|
333 | }
|
---|
334 | );
|
---|
335 | };
|
---|
336 | var c = clear || false;
|
---|
337 | // has to be a string or regular expression (object in IE, function in Firefox)
|
---|
338 | if(vT != "string" && vT != "function" && vT != "object") return this;
|
---|
339 | this.each(
|
---|
340 | function()
|
---|
341 | {
|
---|
342 | if(this.nodeName.toLowerCase() != "select") return this;
|
---|
343 | // get options
|
---|
344 | var o = this.options;
|
---|
345 | // get number of options
|
---|
346 | var oL = o.length;
|
---|
347 | for(var i = 0; i<oL; i++)
|
---|
348 | {
|
---|
349 | if(v.constructor == RegExp)
|
---|
350 | {
|
---|
351 | if(o[i].value.match(v))
|
---|
352 | {
|
---|
353 | o[i].selected = true;
|
---|
354 | }
|
---|
355 | else if(c)
|
---|
356 | {
|
---|
357 | o[i].selected = false;
|
---|
358 | }
|
---|
359 | }
|
---|
360 | else
|
---|
361 | {
|
---|
362 | if(o[i].value == v)
|
---|
363 | {
|
---|
364 | o[i].selected = true;
|
---|
365 | }
|
---|
366 | else if(c)
|
---|
367 | {
|
---|
368 | o[i].selected = false;
|
---|
369 | }
|
---|
370 | }
|
---|
371 | }
|
---|
372 | }
|
---|
373 | );
|
---|
374 | return this;
|
---|
375 | };
|
---|
376 |
|
---|
377 | /**
|
---|
378 | * Copy options to another select
|
---|
379 | *
|
---|
380 | * @name copyOptions
|
---|
381 | * @author Sam Collett (http://www.texotela.co.uk)
|
---|
382 | * @type jQuery
|
---|
383 | * @param String to Element to copy to
|
---|
384 | * @param String which (optional) Specifies which options should be copied - 'all' or 'selected'. Default is 'selected'
|
---|
385 | * @example $("#myselect").copyOptions("#myselect2"); // copy selected options from 'myselect' to 'myselect2'
|
---|
386 | * @example $("#myselect").copyOptions("#myselect2","selected"); // same as above
|
---|
387 | * @example $("#myselect").copyOptions("#myselect2","all"); // copy all options from 'myselect' to 'myselect2'
|
---|
388 | *
|
---|
389 | */
|
---|
390 | $.fn.copyOptions = function(to, which)
|
---|
391 | {
|
---|
392 | var w = which || "selected";
|
---|
393 | if($(to).size() == 0) return this;
|
---|
394 | this.each(
|
---|
395 | function()
|
---|
396 | {
|
---|
397 | if(this.nodeName.toLowerCase() != "select") return this;
|
---|
398 | // get options
|
---|
399 | var o = this.options;
|
---|
400 | // get number of options
|
---|
401 | var oL = o.length;
|
---|
402 | for(var i = 0; i<oL; i++)
|
---|
403 | {
|
---|
404 | if(w == "all" || (w == "selected" && o[i].selected))
|
---|
405 | {
|
---|
406 | $(to).addOption(o[i].value, o[i].text);
|
---|
407 | }
|
---|
408 | }
|
---|
409 | }
|
---|
410 | );
|
---|
411 | return this;
|
---|
412 | };
|
---|
413 |
|
---|
414 | /**
|
---|
415 | * Checks if a select box has an option with the supplied value
|
---|
416 | *
|
---|
417 | * @name containsOption
|
---|
418 | * @author Sam Collett (http://www.texotela.co.uk)
|
---|
419 | * @type Boolean|jQuery
|
---|
420 | * @param String|RegExp value Which value to check for. Can be a string or regular expression
|
---|
421 | * @param Function fn (optional) Function to apply if an option with the given value is found.
|
---|
422 | * Use this if you don't want to break the chaining
|
---|
423 | * @example if($("#myselect").containsOption("val1")) alert("Has an option with the value 'val1'");
|
---|
424 | * @example if($("#myselect").containsOption(/^val/i)) alert("Has an option with the value starting with 'val'");
|
---|
425 | * @example $("#myselect").containsOption("val1", copyoption).doSomethingElseWithSelect(); // calls copyoption (user defined function) for any options found, chain is continued
|
---|
426 | *
|
---|
427 | */
|
---|
428 | $.fn.containsOption = function(value, fn)
|
---|
429 | {
|
---|
430 | var found = false;
|
---|
431 | var v = value;
|
---|
432 | var vT = typeof(v);
|
---|
433 | var fT = typeof(fn);
|
---|
434 | // has to be a string or regular expression (object in IE, function in Firefox)
|
---|
435 | if(vT != "string" && vT != "function" && vT != "object") return fT == "function" ? this: found;
|
---|
436 | this.each(
|
---|
437 | function()
|
---|
438 | {
|
---|
439 | if(this.nodeName.toLowerCase() != "select") return this;
|
---|
440 | // option already found
|
---|
441 | if(found && fT != "function") return false;
|
---|
442 | // get options
|
---|
443 | var o = this.options;
|
---|
444 | // get number of options
|
---|
445 | var oL = o.length;
|
---|
446 | for(var i = 0; i<oL; i++)
|
---|
447 | {
|
---|
448 | if(v.constructor == RegExp)
|
---|
449 | {
|
---|
450 | if (o[i].value.match(v))
|
---|
451 | {
|
---|
452 | found = true;
|
---|
453 | if(fT == "function") fn.call(o[i], i);
|
---|
454 | }
|
---|
455 | }
|
---|
456 | else
|
---|
457 | {
|
---|
458 | if (o[i].value == v)
|
---|
459 | {
|
---|
460 | found = true;
|
---|
461 | if(fT == "function") fn.call(o[i], i);
|
---|
462 | }
|
---|
463 | }
|
---|
464 | }
|
---|
465 | }
|
---|
466 | );
|
---|
467 | return fT == "function" ? this : found;
|
---|
468 | };
|
---|
469 |
|
---|
470 | /**
|
---|
471 | * Returns values which have been selected
|
---|
472 | *
|
---|
473 | * @name selectedValues
|
---|
474 | * @author Sam Collett (http://www.texotela.co.uk)
|
---|
475 | * @type Array
|
---|
476 | * @example $("#myselect").selectedValues();
|
---|
477 | *
|
---|
478 | */
|
---|
479 | $.fn.selectedValues = function()
|
---|
480 | {
|
---|
481 | var v = [];
|
---|
482 | this.selectedOptions().each(
|
---|
483 | function()
|
---|
484 | {
|
---|
485 | v[v.length] = this.value;
|
---|
486 | }
|
---|
487 | );
|
---|
488 | return v;
|
---|
489 | };
|
---|
490 |
|
---|
491 | /**
|
---|
492 | * Returns text which has been selected
|
---|
493 | *
|
---|
494 | * @name selectedTexts
|
---|
495 | * @author Sam Collett (http://www.texotela.co.uk)
|
---|
496 | * @type Array
|
---|
497 | * @example $("#myselect").selectedTexts();
|
---|
498 | *
|
---|
499 | */
|
---|
500 | $.fn.selectedTexts = function()
|
---|
501 | {
|
---|
502 | var t = [];
|
---|
503 | this.selectedOptions().each(
|
---|
504 | function()
|
---|
505 | {
|
---|
506 | t[t.length] = this.text;
|
---|
507 | }
|
---|
508 | );
|
---|
509 | return t;
|
---|
510 | };
|
---|
511 |
|
---|
512 | /**
|
---|
513 | * Returns options which have been selected
|
---|
514 | *
|
---|
515 | * @name selectedOptions
|
---|
516 | * @author Sam Collett (http://www.texotela.co.uk)
|
---|
517 | * @type jQuery
|
---|
518 | * @example $("#myselect").selectedOptions();
|
---|
519 | *
|
---|
520 | */
|
---|
521 | $.fn.selectedOptions = function()
|
---|
522 | {
|
---|
523 | return this.find("option:selected");
|
---|
524 | };
|
---|
525 |
|
---|
526 | })(jQuery); |
---|