JqueryJquery plugins   PortFolioSenamion's PortFolio HomeHome page corner A jquery blog

Senamion.com


Senamion:

Categorie:

jDoubleSelect: jQuery plugin transform one select with optgroups into two selects

10 marzo 2010 by Giovanni

jDoubleSelect is a jQuery plugin to transform one select with optgroups into two selects, the first one with all groups and the second updated with the options of the group selected.

The screenshot:
jDoubleSelect screenshot

See the plugin jDoubleSelect page!

In Jquery | 19 Comments »

19 Comments a “jDoubleSelect: jQuery plugin transform one select with optgroups into two selects”

  1. Giovanni scrive:

    New version 0.1 faster!

  2. rob scrive:

    Great – but when I add a second select to my form, doubleselect takes control of that too and I get two empty dropdown boxes

    one
    two

  3. Giovanni scrive:

    You must attach jDoubleSelect only to your select, eg:

    $("[name=nameOfSelect]").jDoubleSelect();
    
  4. rob scrive:

    Thanks – after a bit of reading about jquery I got it working by replacing select with #zone where zone is the ID of the select element.

  5. Giovanni scrive:

    With $(”[name=nameOfSelect]“)… you select the field with name nameOfSelect.

  6. Giovanni scrive:

    New version 0.2 with new option {text: ‘text’} for text between 2 selects.

  7. Izikd scrive:

    I wouldn’t work if name is something like “data[User][Password]“.
    Especially when using CakePHP.

    To make it work properly changed the line:

    var	name1 = $(this).attr("name") + "_jDS";
    

    TO:

    var	name1 = $(this).attr("id") + "_jDS";
    
  8. Izikd scrive:

    When first select selected, the overall value wouldn’t change to the first value in the second select.

    FIND:

    el.next().next().after(""+el.find("optgroup[label="+$(this).val()+"]").html()+"");
    

    AFTER ADD:

    el.val($("#"+name2).val());
    
  9. Giovanni scrive:

    Thank you very much, but second solution is very very slow in firefox, I tested also:

    $("#"+name2).trigger("change");
    

    But is slow too, I must think a solution…

  10. Izikd scrive:

    For some reason the problem is on setting value on `el`.
    For example: `el.val(100)` (even if it’s just a number!)
    It makes the slowness.

    With original version 0.3, on Demo2 you have performance issue when selecting 2nd select.

    This seems like fixing the issue:
    FIND:

    el.val($(this).val());
    

    REPLACE WITH:

    el.attr("value", $(this).val());
    

    FIND:

    el.next().next().after(""+el.find("optgroup[label="+$(this).val()+"]").html()+"");
    

    AFTER ADD:

    $("#"+name2).trigger("change");
    

    Please insure that using `attr(”value”, value)` gives the same result as `val(value)`.

  11. Giovanni scrive:

    I don’t understand why, but with el.attr(”value”, $(this).val()); is fast! I think is a jQuery problem!
    Thank you very much Izikd!!!

  12. Izikd scrive:

    Glad to help ;)

  13. N8 scrive:

    Looks like an interesting plug-in. Does it support multiple selects? If it can be made to work with multiple selects, I think it would be a good fit for a current project.

  14. Giovanni scrive:

    For multiselect you can use this plugin!

  15. Attiks scrive:

    Anybody else having problems with IE7, I guess I’m facing a timing issue because the value isn’t passed to the form handler. All other browsers are working.

  16. Alex scrive:

    Here’s a change that’ll make the component work for not just optgroups but also options not included in opt groups

    		$(this).children().each(function(i) {
    				// Verify disabled or selected group
    				if ($(this).attr("disabled"))
    					s = " disabled ";
    				else if ($(this).find(":selected").attr("value")) {
    					s = " selected ";
    					}
    				else s = "";
    				if($(this).attr("label")){//check if the child is option group
    					groupSel += ""+$(this).attr("label")+"";
    				} else {
    					groupSel += ""+$(this).html()+"";
    				}
    			});
    			$(this).hide().after(""+groupSel+" "+o.text+"");
    
    			$("#"+name1).change(function(){
    				// REMOVE OLD ELEMENT, ADD NEW SELECT, BIND CHANGE EVENT AND TRIGGER IT
    				$("#"+name2).remove();
    
    				if(el.find("optgroup[label="+$(this).val()+"]").length > 0){//if option group
    					el.next().next().after(""+el.find("optgroup[label="+$(this).val()+"]").html()+"");
    				} else {//else option
    					el.attr("value", $(this).val());
    				}
    
    				//el.val($("#"+name2).val());
    				$("#"+name2).trigger("change");
    			});
    

  17. Paolo scrive:

    It might be a good idea to trigger the original element change event.

    			$("#"+name2).live("change", function(){
    				// THIS IS VERY VERY SLOW IN FIREFOX
    				//el.val($(this).val());
    				el.attr("value", $(this).val());
    --->			el.trigger("change");
    			}).trigger("change");
    

  18. Mauro Zadunaisky scrive:

    In reply to this:

    `Great – but when I add a second select to my form, doubleselect takes control of that too and I get two empty dropdown boxes`

    I’ve fixed the code and solved that problem. You can find the complete modified script at http://codaset.com/plusglobal/browniephp/source/master/blob/webroot/js/jquery.jDoubleSelect.js

    (in only added an if statement in line 39)

  19. mark scrive:

    SO – i just updated things to work in jQuery 1.6.1:

    
    /*
    * jDoubleSelect jQuery plugin
    *
    * Copyright (c) 2010 Giovanni Casassa (senamion.com - senamion.it)
    *
    * Dual licensed under the MIT (MIT-LICENSE.txt)
    * and GPL (GPL-LICENSE.txt) licenses.
    *
    * http://www.senamion.com
    *
    */
    
    (function ($) {
        jQuery.fn.jDoubleSelect = function (o) {
    
            o = $.extend({
                text: ""
            }, o);
    
            return this.each(function () {
                var el = $(this);
                var p = el.parent();
                var name1 = (el.attr('id') || el.attr('name') || el.attr('class') || 'internalName') + '_jDS';
                var name2 = name1 + "_2";
    
                groupSel = "";
                $(this).children().each(function (i) {
                    // Verify disabled or selected group
                    if ($(this).attr("disabled"))
                        s = " disabled ";
                    else if ($(this).find(":selected").attr("value") || $(this).attr('selected')) {
                        s = " selected ";
                    }
                    else s = "";
    
                    if ($(this).attr("label"))
                        groupSel += "" + $(this).attr("label") + "";
                    else
                        groupSel += "" + $(this).text() + "";
                });
                $(this).hide().after("" + groupSel + "");
    
                $("#" + name1).bind("change keyup",function () {
                    $("#" + name2).add($("#" + name2).prev()).remove();
                    var o = el.find("optgroup[label=\"" + $(this).val() + "\"]").html();
                    if (o) {
                        el.next().after(" " + (el.attr("data-doubleSelect-innerLabel") || "") + " " + o + "");
                        $("#" + name2).trigger("change");
                        p.removeClass("jDoubleSelect-showing1").addClass("jDoubleSelect-showing2");
                    } else {
                        el.attr("value", $(this).val());
                        p.removeClass("jDoubleSelect-showing2").addClass("jDoubleSelect-showing1");
                    }
                });
    
                $("#" + name2).live("change keyup", function () {
                    el.attr("value", $(this).val());
                }).trigger("change");
    
                $("#" + name1).trigger("change")
            });
        };
    })(jQuery);
    

Write a comment