swserg
swserg

Reputation: 722

Jquery dynamic options remove/add in select forms

I have following simple Html code with 2 SELECT forms with identical options values:

<select id="first">
    <option value="none">None</option>
    <option value="one">Toyota</option>
    <option value="two">Nissan</option>
</select>

<select id="second">
    <option value="none">None</option>
    <option value="one">Toyota</option>
    <option value="two">Nissan</option>
</select>

I am writing a jquery script that should do following: if in the #first select I choose any value except "none", f.e. Toyota, it will automatically disappear from the #second select:

<select id="second">
    <option value="none">None</option>
    <option value="two">Nissan</option>
</select>

further, if I choose Nissan in the #second select(assuming #first still have Toyota selected), it should automatically disappear from the #first select:

<select id="first">
    <option selected="selected" value="one">Toyota</option>
    <option value="none">None</option>
</select>

At the end, when I reset selector to "None" in any select form, it should recreate that option in another select on the same position.

How is that better to achieve? is it better to use .remove()/.append() actions or .hide()/.unhide()? So far I create following snippet:

$(document).on('change','select', function() {
   var sel = $(this).attr('id');
   var val = $(this).val();

if ( sel === "first" && val != "none") {
    $("#second option[value="+val+"]").remove();
} else if ( sel === "second" && val != "none") {
    $("#first option[value="+val+"]").remove();
}

this just removes selected option from another select, but how to correctly re-create option on the same position after changing select to "None"?

UPDATE: .hide() function doesn't work in some browsers, I need to use .remove()/.append(), but the problem is that how to append to the position that it was before?

Upvotes: 6

Views: 23461

Answers (4)

am71722
am71722

Reputation: 129

jsFiddle

As long as you have a way to group the selects together this will work. In this case, I just used a class. Also, there is a better way to set your starting point for each select than hard coding it. Setting prefText to: jQuery(".onlySelectOnce:first").html() would probably work.

var prefArr = ["one", "two", "three"];
var prefText = ['<option value="">None</option>',
'<option value="one">Toyota</option>',
'<option value="two">Nissan</option>',
'<option value="three">Dodge</option>'];

jQuery('#content').on("change","select[name^=pref]",function(){
        var selectedPrefs = [];
        //What items are selected
        jQuery("select[name^=pref]").each(function(){
            selectedPrefs.push(jQuery(this).val());
        });
        //make sure to add selection back to other selects
        jQuery("select[name^=pref]").each(function(i,select){
            jQuery(select).empty();
            jQuery(select).append(prefText);
            var elZero = selectedPrefs[i];
            jQuery(select).val(elZero);
            console.log(jQuery(select).prop("name")+" "+i+" "+elZero);
        });
        //remove already selected options
        jQuery("select[name^=pref]").each(function(i,select){
            jQuery("select[name^=pref] option").each(function(ii,option){
                if(jQuery(option).val() != "" && selectedPrefs[i] == jQuery(option).val() && selectedPrefs[i] != jQuery(option).parent().val()){
                    jQuery(option).remove();
                }
            });
        });
    });

Upvotes: 2

BillJam
BillJam

Reputation: 221

How about this for N number of SELECT's (as for Secret Questions). If you are lucky enough to not be stuck with having to support IE, you can substitute Hide & Show for prop('disabled', true) and prop('disabled', false). Wish I could.

var lastQuestion;
$("select").bind('click keyup', function (event) {
    lastQuestion = $(event.srcElement).val();
});

$("select").bind('change', function (event) {
    $("select").not(event.srcElement).each(function (index) {
        if(lastQuestion != '')
            $("#" + this.id + " option[value='" + lastQuestion + "']").prop('disabled', false);
        if ($(event.srcElement).val() != "") {
            $("#" + this.id + " option[value='" + $(event.srcElement).val() + "']").prop('disabled', true);
        }
        //$("#" + this.id).val("");
    });
});

Upvotes: 0

JustinM151
JustinM151

Reputation: 744

Here is another, more dynamic method of doing what you want. I think this one would be the best option.

http://jsfiddle.net/rK7tJ/1/

$("#first").change(function() {
    if($("#first").val() != "none") {
        $("#second option[value!="+$("#first").val()+"]").show();
        $("#second option[value="+$("#first").val()+"]").hide();
    } else {
        $("#second option[value!="+$("#first").val()+"]").show();
    }
    $("#second").val('none');
});

$("#second").change(function() {
    if($("#second").val() != "none") {
        $("#first option[value!="+$("#second").val()+"]").show();
        $("#first option[value="+$("#second").val()+"]").hide();
    } else {
        $("#first option[value!="+$("#second").val()+"]").show();
    }
    $("#first").val('none');
});

Upvotes: 5

JustinM151
JustinM151

Reputation: 744

After removing an option, you can add one back with .append:

$('#selectID').append($("<option></option>").attr("value","SomeVal").text("SomeText"));

EDIT: I think this is what you are trying to do right? http://jsfiddle.net/zdZ3d/

$("#first").change(function() {
switch($("#first").val()) {
    case "one":
        $("#second option[value='one']").hide();
        $("#second option[value!='one']").show();
        $("#second").val("none");
        break;
    case "two":
        $("#second option[value='two']").hide();
        $("#second option[value!='two']").show();
        $("#second").val("none");
        break;
    case "none":
        $("#second option[value='one']").show();
        $("#second option[value!='two']").show();
        $("#second").val("none");
        break;
}
});

$("#second").change(function() {
switch($("#second").val()) {
    case "one":
        $("#first option[value='one']").hide();
        $("#first option[value!='one']").show();
        $("#first").val("none");
        break;
    case "two":
        $("#first option[value='two']").hide();
        $("#first option[value!='two']").show();
        $("#first").val("none");
        break;
    case "none":
        $("#first option[value='one']").show();
        $("#first option[value!='two']").show();
        $("#first").val("none");
        break;
}
});

Upvotes: 1

Related Questions