/* * * Copyright (c) 2006-2009 Sam Collett (http://www.texotela.co.uk) * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. * * Version 2.2.4 * 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 * @example  $("#myselect").removeOption(["myselect_1","myselect_2"]); // values contained in passed array * */$.fn.removeOption = function(){        var a = arguments;        if(a.length == 0) return this;        var ta = typeof(a[0]);        var v, index;        // has to be a string or regular expression (object in IE, function in Firefox)        if(ta == "string" || ta == "object" || ta == "function" )        {                v = a[0];                // if an array, remove items                if(v.constructor == Array)                {                        var l = v.length;                        for(var i = 0; i<l; i++)                        {                                this.removeOption(v[i], a[1]);                         }                        return this;                }        }        else if(ta == "number") index = 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                        {                                // only remove if selected?                                if(a[1] === true)                                {                                        remove = o[index].selected;                                }                                else                                {                                        remove = true;                                }                                if(remove)                                {                                        this.remove(index);                                }                        }                }        );        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){        // get selected values first        var sel = $(this).selectedValues();        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;                        }                }        ).selectOptions(sel, true); // select values, clearing existing ones        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|Array value  Which options should be selected * can be a string or regular expression, or an array of strings / regular expressions * @param    Boolean clear  Clear existing selected options, default false * @example  $("#myselect").selectOptions("val1"); // with the value 'val1' * @example  $("#myselect").selectOptions(["val1","val2","val3"]); // with the values 'val1' 'val2' 'val3' * @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);        // handle arrays        if(vT == "object" && v.constructor == Array)        {                var $this = this;                $.each(v, function()                        {                                $this.selectOptions(this, clear);                        }                );        };        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], i);                                        }                                }                                else                                {                                        if (o[i].value == v)                                        {                                                found = true;                                                if(fT == "function") fn.call(o[i], i);                                        }                                }                        }                }        );        return fT == "function" ? this : found;};/** * Returns values which have been selected * * @name     selectedValues * @author   Sam Collett (http://www.texotela.co.uk) * @type     Array * @example  $("#myselect").selectedValues(); * */$.fn.selectedValues = function(){        var v = [];        this.selectedOptions().each(                function()                {                        v[v.length] = this.value;                }        );        return v;};/** * Returns text which has been selected * * @name     selectedTexts * @author   Sam Collett (http://www.texotela.co.uk) * @type     Array * @example  $("#myselect").selectedTexts(); * */$.fn.selectedTexts = function(){        var t = [];        this.selectedOptions().each(                function()                {                        t[t.length] = this.text;                }        );        return t;};/** * Returns options which have been selected * * @name     selectedOptions * @author   Sam Collett (http://www.texotela.co.uk) * @type     jQuery * @example  $("#myselect").selectedOptions(); * */$.fn.selectedOptions = function(){        return this.find("option:selected");};})(jQuery);