/* * * Copyright (c) 2006/2007 Sam Collett (http://www.texotela.co.uk) * Licensed under the MIT License: * http://www.opensource.org/licenses/mit-license.php * * Version 2.1 * Demo: http://www.texotela.co.uk/code/jquery/select/ * * $LastChangedDate$ * $Rev$ * */ (function($) { /** * Adds (single/multiple) options to a select box (or series of select boxes) * * @name     addOption * @author   Sam Collett (http://www.texotela.co.uk) * @type     jQuery * @example  $("#myselect").addOption("Value", "Text"); // add single value (will be selected) * @example  $("#myselect").addOption("Value 2", "Text 2", false); // add single value (won't be selected) * @example  $("#myselect").addOption({"foo":"bar","bar":"baz"}, false); // add multiple values, but don't select * */$.fn.addOption = function(){	var add = function(el, v, t, sO)	{		var option = document.createElement("option");		option.value = v, option.text = t;		// get options		var o = el.options;		// get number of options		var oL = o.length;		if(!el.cache)		{			el.cache = {};			// loop through existing options, adding to cache			for(var i = 0; i < oL; i++)			{				el.cache[o[i].value] = i;			}		}		// add to cache if it isn't already		if(typeof el.cache[v] == "undefined") el.cache[v] = oL;		el.options[el.cache[v]] = option;		if(sO)		{			option.selected = true;		}	};		var a = arguments;	if(a.length == 0) return this;	// select option when added? default is true	var sO = true;	// multiple items	var m = false;	// other variables	var items, v, t;	if(typeof(a[0]) == "object")	{		m = true;		items = a[0];	}	if(a.length >= 2)	{		if(typeof(a[1]) == "boolean") sO = a[1];		else if(typeof(a[2]) == "boolean") sO = a[2];		if(!m)		{			v = a[0];			t = a[1];		}	}	this.each(		function()		{			if(this.nodeName.toLowerCase() != "select") return;			if(m)			{				for(var item in items)				{					add(this, item, items[item], sO);				}			}			else			{				add(this, v, t, sO);			}		}	);	return this;};/** * Add options via ajax * * @name     ajaxAddOption * @author   Sam Collett (http://www.texotela.co.uk) * @type     jQuery * @param    String url      Page to get options from (must be valid JSON) * @param    Object params   (optional) Any parameters to send with the request * @param    Boolean select  (optional) Select the added options, default true * @param    Function fn     (optional) Call this function with the select object as param after completion * @param    Array args      (optional) Array with params to pass to the function afterwards * @example  $("#myselect").ajaxAddOption("myoptions.php"); * @example  $("#myselect").ajaxAddOption("myoptions.php", {"code" : "007"}); * @example  $("#myselect").ajaxAddOption("myoptions.php", {"code" : "007"}, false, sortoptions, {"dir": "desc"}); * */$.fn.ajaxAddOption = function(url, params, select, fn, args){	if(typeof(url) != "string") return this;	if(typeof(params) != "object") params = {};	if(typeof(select) != "boolean") select = true;	this.each(		function()		{			var el = this;			$.getJSON(url,				params,				function(r)				{					$(el).addOption(r, select);					if(typeof fn == "function")					{						if(typeof args == "object")						{							fn.apply(el, args);						} 						else						{							fn.call(el);						}					}				}			);		}	);	return this;};/** * Removes an option (by value or index) from a select box (or series of select boxes) * * @name     removeOption * @author   Sam Collett (http://www.texotela.co.uk) * @type     jQuery * @param    String|RegExp|Number what  Option to remove * @param    Boolean selectedOnly       (optional) Remove only if it has been selected (default false)    * @example  $("#myselect").removeOption("Value"); // remove by value * @example  $("#myselect").removeOption(/^val/i); // remove options with a value starting with 'val' * @example  $("#myselect").removeOption(/./); // remove all options * @example  $("#myselect").removeOption(/./, true); // remove all options that have been selected * @example  $("#myselect").removeOption(0); // remove by index * */$.fn.removeOption = function(){	var a = arguments;	if(a.length == 0) return this;	var ta = typeof(a[0]);	var v, i;	// has to be a string or regular expression (object in IE, function in Firefox)	if(ta == "string" || ta == "object" || ta == "function" ) v = a[0];	else if(ta == "number") i = a[0];	else return this;	this.each(		function()		{			if(this.nodeName.toLowerCase() != "select") return;			// clear cache			if(this.cache) this.cache = null;			// does the option need to be removed?			var remove = false;			// get options			var o = this.options;			if(!!v)			{				// get number of options				var oL = o.length;				for(var i=oL-1; i>=0; i--)				{					if(v.constructor == RegExp)					{						if(o[i].value.match(v))						{							remove = true;						}					}					else if(o[i].value == v)					{						remove = true;					}					// if the option is only to be removed if selected					if(remove && a[1] === true) remove = o[i].selected;					if(remove)					{						o[i] = null;					}					remove = false;				}			}			else			{				if(remove && a[1] === true) remove = o[i].selected;				if(remove)				{					this.remove(i);				}			}		}	);	return this;};/** * Sort options (ascending or descending) in a select box (or series of select boxes) * * @name     sortOptions * @author   Sam Collett (http://www.texotela.co.uk) * @type     jQuery * @param    Boolean ascending   (optional) Sort ascending (true/undefined), or descending (false) * @example  // ascending * $("#myselect").sortOptions(); // or $("#myselect").sortOptions(true); * @example  // descending * $("#myselect").sortOptions(false); * */$.fn.sortOptions = function(ascending){	var a = typeof(ascending) == "undefined" ? true : !!ascending;	this.each(		function()		{			if(this.nodeName.toLowerCase() != "select") return;			// get options			var o = this.options;			// get number of options			var oL = o.length;			// create an array for sorting			var sA = [];			// loop through options, adding to sort array			for(var i = 0; i<oL; i++)			{				sA[i] = {					v: o[i].value,					t: o[i].text				}			}			// sort items in array			sA.sort(				function(o1, o2)				{					// option text is made lowercase for case insensitive sorting					o1t = o1.t.toLowerCase(), o2t = o2.t.toLowerCase();					// if options are the same, no sorting is needed					if(o1t == o2t) return 0;					if(a)					{						return o1t < o2t ? -1 : 1;					}					else					{						return o1t > o2t ? -1 : 1;					}				}			);			// change the options to match the sort array			for(var i = 0; i<oL; i++)			{				o[i].text = sA[i].t;				o[i].value = sA[i].v;			}		}	);	return this;};/** * Selects an option by value * * @name     selectOptions * @author   Mathias Bank (http://www.mathias-bank.de), original function * @author   Sam Collett (http://www.texotela.co.uk), addition of regular expression matching * @type     jQuery * @param    String|RegExp value  Which options should be selected * can be a string or regular expression * @param    Boolean clear  Clear existing selected options, default false * @example  $("#myselect").selectOptions("val1"); // with the value 'val1' * @example  $("#myselect").selectOptions(/^val/i); // with the value starting with 'val', case insensitive * */$.fn.selectOptions = function(value, clear){	var v = value;	var vT = typeof(value);	var c = clear || false;	// has to be a string or regular expression (object in IE, function in Firefox)	if(vT != "string" && vT != "function" && vT != "object") return this;	this.each(		function()		{			if(this.nodeName.toLowerCase() != "select") return this;			// get options			var o = this.options;			// get number of options			var oL = o.length;			for(var i = 0; i<oL; i++)			{				if(v.constructor == RegExp)				{					if(o[i].value.match(v))					{						o[i].selected = true;					}					else if(c)					{						o[i].selected = false;					}				}				else				{					if(o[i].value == v)					{						o[i].selected = true;					}					else if(c)					{						o[i].selected = false;					}				}			}		}	);	return this;};/** * Copy options to another select * * @name     copyOptions * @author   Sam Collett (http://www.texotela.co.uk) * @type     jQuery * @param    String to  Element to copy to * @param    String which  (optional) Specifies which options should be copied - 'all' or 'selected'. Default is 'selected' * @example  $("#myselect").copyOptions("#myselect2"); // copy selected options from 'myselect' to 'myselect2' * @example  $("#myselect").copyOptions("#myselect2","selected"); // same as above * @example  $("#myselect").copyOptions("#myselect2","all"); // copy all options from 'myselect' to 'myselect2' * */$.fn.copyOptions = function(to, which){	var w = which || "selected";	if($(to).size() == 0) return this;	this.each(		function()		{			if(this.nodeName.toLowerCase() != "select") return this;			// get options			var o = this.options;			// get number of options			var oL = o.length;			for(var i = 0; i<oL; i++)			{				if(w == "all" ||	(w == "selected" && o[i].selected))				{					$(to).addOption(o[i].value, o[i].text);				}			}		}	);	return this;};/** * Checks if a select box has an option with the supplied value * * @name     containsOption * @author   Sam Collett (http://www.texotela.co.uk) * @type     Boolean|jQuery * @param    String|RegExp value  Which value to check for. Can be a string or regular expression * @param    Function fn          (optional) Function to apply if an option with the given value is found. * Use this if you don't want to break the chaining * @example  if($("#myselect").containsOption("val1")) alert("Has an option with the value 'val1'"); * @example  if($("#myselect").containsOption(/^val/i)) alert("Has an option with the value starting with 'val'"); * @example  $("#myselect").containsOption("val1", copyoption).doSomethingElseWithSelect(); // calls copyoption (user defined function) for any options found, chain is continued * */$.fn.containsOption = function(value, fn){	var found = false;	var v = value;	var vT = typeof(v);	var fT = typeof(fn);	// has to be a string or regular expression (object in IE, function in Firefox)	if(vT != "string" && vT != "function" && vT != "object") return fT == "function" ? this: found;	this.each(		function()		{			if(this.nodeName.toLowerCase() != "select") return this;			// option already found			if(found && fT != "function") return false;			// get options			var o = this.options;			// get number of options			var oL = o.length;			for(var i = 0; i<oL; i++)			{				if(v.constructor == RegExp)				{					if (o[i].value.match(v))					{						found = true;						if(fT == "function") fn.call(o[i]);					}				}				else				{					if (o[i].value == v)					{						found = true;						if(fT == "function") fn.call(o[i]);					}				}			}		}	);	return fT == "function" ? this : found;};})(jQuery);
