3 * Copyright (c) 2006-2010 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.
8 * Demo: http://www.texotela.co.uk/code/jquery/select/
16 * Adds (single/multiple) options to a select box (or series of select boxes)
19 * @author Sam Collett (http://www.texotela.co.uk)
21 * @example $("#myselect").addOption("Value", "Text"); // add single value (will be selected)
22 * @example $("#myselect").addOption("Value 2", "Text 2", false); // add single value (won't be selected)
23 * @example $("#myselect").addOption({"foo":"bar","bar":"baz"}, false); // add multiple values, but don't select
26 $.fn.addOption = function()
28 var add = function(el, v, t, sO, index)
30 var option = document.createElement("option");
31 option.value = v, option.text = t;
34 // get number of options
39 // loop through existing options, adding to cache
40 for(var i = 0; i < oL; i++)
42 el.cache[o[i].value] = i;
45 if (index || index == 0)
47 // we're going to insert these starting at a specific index...
48 // this has the side effect of el.cache[v] being the
49 // correct value for the typeof check below
51 for(var ii =index; ii <= oL; ii++)
53 var tmp = el.options[ii];
56 el.cache[o[ii].value] = ii;
61 // add to cache if it isn't already
62 if(typeof el.cache[v] == "undefined") el.cache[v] = oL;
63 el.options[el.cache[v]] = option;
66 option.selected = true;
71 if(a.length == 0) return this;
72 // select option when added? default is true
78 if(typeof(a[0]) == "object")
85 if(typeof(a[1]) == "boolean")
90 else if(typeof(a[2]) == "boolean")
108 if(this.nodeName.toLowerCase() != "select") return;
111 for(var item in items)
113 add(this, item, items[item], sO, startindex);
119 add(this, v, t, sO, startindex);
127 * Add options via ajax
129 * @name ajaxAddOption
130 * @author Sam Collett (http://www.texotela.co.uk)
132 * @param String url Page to get options from (must be valid JSON)
133 * @param Object params (optional) Any parameters to send with the request
134 * @param Boolean select (optional) Select the added options, default true
135 * @param Function fn (optional) Call this function with the select object as param after completion
136 * @param Array args (optional) Array with params to pass to the function afterwards
137 * @example $("#myselect").ajaxAddOption("myoptions.php");
138 * @example $("#myselect").ajaxAddOption("myoptions.php", {"code" : "007"});
139 * @example $("#myselect").ajaxAddOption("myoptions.php", {"code" : "007"}, false, sortoptions, [{"dir": "desc"}]);
142 $.fn.ajaxAddOption = function(url, params, select, fn, args)
144 if(typeof(url) != "string") return this;
145 if(typeof(params) != "object") params = {};
146 if(typeof(select) != "boolean") select = true;
155 $(el).addOption(r, select);
156 if(typeof fn == "function")
158 if(typeof args == "object")
175 * Removes an option (by value or index) from a select box (or series of select boxes)
178 * @author Sam Collett (http://www.texotela.co.uk)
180 * @param String|RegExp|Number what Option to remove
181 * @param Boolean selectedOnly (optional) Remove only if it has been selected (default false)
182 * @example $("#myselect").removeOption("Value"); // remove by value
183 * @example $("#myselect").removeOption(/^val/i); // remove options with a value starting with 'val'
184 * @example $("#myselect").removeOption(/./); // remove all options
185 * @example $("#myselect").removeOption(/./, true); // remove all options that have been selected
186 * @example $("#myselect").removeOption(0); // remove by index
187 * @example $("#myselect").removeOption(["myselect_1","myselect_2"]); // values contained in passed array
190 $.fn.removeOption = function()
193 if(a.length == 0) return this;
194 var ta = typeof(a[0]);
196 // has to be a string or regular expression (object in IE, function in Firefox)
197 if(ta == "string" || ta == "object" || ta == "function" )
200 // if an array, remove items
201 if(v.constructor == Array)
204 for(var i = 0; i<l; i++)
206 this.removeOption(v[i], a[1]);
211 else if(ta == "number") index = a[0];
216 if(this.nodeName.toLowerCase() != "select") return;
218 if(this.cache) this.cache = null;
219 // does the option need to be removed?
222 var o = this.options;
225 // get number of options
227 for(var i=oL-1; i>=0; i--)
229 if(v.constructor == RegExp)
231 if(o[i].value.match(v))
236 else if(o[i].value == v)
240 // if the option is only to be removed if selected
241 if(remove && a[1] === true) remove = o[i].selected;
251 // only remove if selected?
254 remove = o[index].selected;
271 * Sort options (ascending or descending) in a select box (or series of select boxes)
274 * @author Sam Collett (http://www.texotela.co.uk)
276 * @param Boolean ascending (optional) Sort ascending (true/undefined), or descending (false)
277 * @example // ascending
278 * $("#myselect").sortOptions(); // or $("#myselect").sortOptions(true);
279 * @example // descending
280 * $("#myselect").sortOptions(false);
283 $.fn.sortOptions = function(ascending)
285 // get selected values first
286 var sel = $(this).selectedValues();
287 var a = typeof(ascending) == "undefined" ? true : !!ascending;
291 if(this.nodeName.toLowerCase() != "select") return;
293 var o = this.options;
294 // get number of options
296 // create an array for sorting
298 // loop through options, adding to sort array
299 for(var i = 0; i<oL; i++)
306 // sort items in array
310 // option text is made lowercase for case insensitive sorting
311 o1t = o1.t.toLowerCase(), o2t = o2.t.toLowerCase();
312 // if options are the same, no sorting is needed
313 if(o1t == o2t) return 0;
316 return o1t < o2t ? -1 : 1;
320 return o1t > o2t ? -1 : 1;
324 // change the options to match the sort array
325 for(var i = 0; i<oL; i++)
328 o[i].value = sA[i].v;
331 ).selectOptions(sel, true); // select values, clearing existing ones
335 * Selects an option by value
337 * @name selectOptions
338 * @author Mathias Bank (http://www.mathias-bank.de), original function
339 * @author Sam Collett (http://www.texotela.co.uk), addition of regular expression matching
341 * @param String|RegExp|Array value Which options should be selected
342 * can be a string or regular expression, or an array of strings / regular expressions
343 * @param Boolean clear Clear existing selected options, default false
344 * @example $("#myselect").selectOptions("val1"); // with the value 'val1'
345 * @example $("#myselect").selectOptions(["val1","val2","val3"]); // with the values 'val1' 'val2' 'val3'
346 * @example $("#myselect").selectOptions(/^val/i); // with the value starting with 'val', case insensitive
349 $.fn.selectOptions = function(value, clear)
352 var vT = typeof(value);
354 if(vT == "object" && v.constructor == Array)
359 $this.selectOptions(this, clear);
363 var c = clear || false;
364 // has to be a string or regular expression (object in IE, function in Firefox)
365 if(vT != "string" && vT != "function" && vT != "object") return this;
369 if(this.nodeName.toLowerCase() != "select") return this;
371 var o = this.options;
372 // get number of options
374 for(var i = 0; i<oL; i++)
376 if(v.constructor == RegExp)
378 if(o[i].value.match(v))
380 o[i].selected = true;
384 o[i].selected = false;
391 o[i].selected = true;
395 o[i].selected = false;
405 * Copy options to another select
408 * @author Sam Collett (http://www.texotela.co.uk)
410 * @param String to Element to copy to
411 * @param String which (optional) Specifies which options should be copied - 'all' or 'selected'. Default is 'selected'
412 * @example $("#myselect").copyOptions("#myselect2"); // copy selected options from 'myselect' to 'myselect2'
413 * @example $("#myselect").copyOptions("#myselect2","selected"); // same as above
414 * @example $("#myselect").copyOptions("#myselect2","all"); // copy all options from 'myselect' to 'myselect2'
417 $.fn.copyOptions = function(to, which)
419 var w = which || "selected";
420 if($(to).size() == 0) return this;
424 if(this.nodeName.toLowerCase() != "select") return this;
426 var o = this.options;
427 // get number of options
429 for(var i = 0; i<oL; i++)
431 if(w == "all" || (w == "selected" && o[i].selected))
433 $(to).addOption(o[i].value, o[i].text);
442 * Checks if a select box has an option with the supplied value
444 * @name containsOption
445 * @author Sam Collett (http://www.texotela.co.uk)
446 * @type Boolean|jQuery
447 * @param String|RegExp value Which value to check for. Can be a string or regular expression
448 * @param Function fn (optional) Function to apply if an option with the given value is found.
449 * Use this if you don't want to break the chaining
450 * @example if($("#myselect").containsOption("val1")) alert("Has an option with the value 'val1'");
451 * @example if($("#myselect").containsOption(/^val/i)) alert("Has an option with the value starting with 'val'");
452 * @example $("#myselect").containsOption("val1", copyoption).doSomethingElseWithSelect(); // calls copyoption (user defined function) for any options found, chain is continued
455 $.fn.containsOption = function(value, fn)
461 // has to be a string or regular expression (object in IE, function in Firefox)
462 if(vT != "string" && vT != "function" && vT != "object") return fT == "function" ? this: found;
466 if(this.nodeName.toLowerCase() != "select") return this;
467 // option already found
468 if(found && fT != "function") return false;
470 var o = this.options;
471 // get number of options
473 for(var i = 0; i<oL; i++)
475 if(v.constructor == RegExp)
477 if (o[i].value.match(v))
480 if(fT == "function") fn.call(o[i], i);
488 if(fT == "function") fn.call(o[i], i);
494 return fT == "function" ? this : found;
498 * Returns values which have been selected
500 * @name selectedValues
501 * @author Sam Collett (http://www.texotela.co.uk)
503 * @example $("#myselect").selectedValues();
506 $.fn.selectedValues = function()
509 this.selectedOptions().each(
512 v[v.length] = this.value;
519 * Returns text which has been selected
521 * @name selectedTexts
522 * @author Sam Collett (http://www.texotela.co.uk)
524 * @example $("#myselect").selectedTexts();
527 $.fn.selectedTexts = function()
530 this.selectedOptions().each(
533 t[t.length] = this.text;
540 * Returns options which have been selected
542 * @name selectedOptions
543 * @author Sam Collett (http://www.texotela.co.uk)
545 * @example $("#myselect").selectedOptions();
548 $.fn.selectedOptions = function()
550 return this.find("option:selected");