Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to repopulate an Html Select's Options without firing the Change event (using jQuery)?

I have multiple selects:

<select id="one">
  <option value="1">one</option>
  <option value="2">two</option>
  <option value="3">three</option>
</select>
<select id="two">
  <option value="1">one</option>
  <option value="2">two</option>
  <option value="3">three</option>
</select>

What I want is to select "one" from the first select, then have that option be removed from the second one. Then if you select "two" from the second one, I want that one removed from the first one.

Here's the JS I have currently:

$(function () {
    var $one = $("#one");
    var $two = $("#two");

    var selectOptions = [];
    $("select").each(function (index) {
        selectOptions[index] = [];
        for (var i = 0; i < this.options.length; i++) {
            selectOptions[index][i] = this.options[i];
        }
    });

    $one.change(function () {
        var selectedValue = $("option:selected", this).val();
        for (var i = 0; i < selectOptions[1].length; i++) {
            var exists = false;
            for (var x = 0; x < $two[0].options.length; x++) {
                if ($two[0].options[x].value == selectOptions[1][i].value)
                    exists = true;
            }
            if (!exists)
                $two.append(selectOptions[1][i]);
        }

        $("option[value='" + selectedValue + "']", $two).remove();
    });
    $two.change(function () {
        var selectedValue = $("option:selected", this).val();
        for (var i = 0; i < selectOptions[0].length; i++) {
            var exists = false;
            for (var x = 0; x < $one[0].options.length; x++) {
                if ($one[0].options[x].value == selectOptions[0][i].value)
                    exists = true;
            }
            if (!exists)
                $one.append(selectOptions[0][i]);
        }

        $("option[value='" + selectedValue + "']", $one).remove();
    });
});

But when the elements get repopulated, it fires the change event in the select whose options are changing. I tried just setting the disabled attribute on the option I want to remove, but that doesn't work with IE6.

like image 452
travis Avatar asked Sep 04 '08 22:09

travis


People also ask

How to remove option using jQuery?

Approach: Select the option from select which needs to remove. Use JQuery remove() method to remove the option from the HTML document.

How to remove all options of select in JavaScript?

We select all the options in the select box using the find() method with a parameter of “option“. Then, we remove all the selected options using the remove() method.


2 Answers

I am not (currently) a user of jQuery, but I can tell you that you need to temporarily disconnect your event handler while you repopulate the items or, at the least, set a flag that you then test for and based on its value, handle the change.

like image 181
Jason Bunting Avatar answered Oct 05 '22 17:10

Jason Bunting


Here's the final code that I ended up using, the flag (changeOnce) worked great, thanks @Jason.

$(function () {
    var $one = $("#one");
    var $two = $("#two");

    var selectOptions = [];
    $("select").each(function (index) {
        selectOptions[index] = [];
        for (var i = 0; i < this.options.length; i++) {
            selectOptions[index][i] = this.options[i];
        }
    });

    var changeOnce = false;
    $one.change(function () {
        if (changeOnce) return;
        changeOnce = true;
        var selectedValue = $("option:selected", this).val();
        filterSelect(selectedValue, $two, 1);
        changeOnce = false;
    });
    $two.change(function () {
        if (changeOnce) return;
        changeOnce = true;
        var selectedValue = $("option:selected", this).val();
        filterSelect(selectedValue, $one, 0);
        changeOnce = false;
    });

    function filterSelect(selectedValue, $selectToFilter, selectIndex) {
        for (var i = 0; i < selectOptions[selectIndex].length; i++) {
            var exists = false;
            for (var x = 0; x < $selectToFilter[0].options.length; x++) {
                if ($selectToFilter[0].options[x].value == selectOptions[selectIndex][i].value)
                    exists = true;
            }
            if (!exists)
                $selectToFilter.append(selectOptions[selectIndex][i]);
        }
        $("option[value='" + selectedValue + "']", $selectToFilter).remove();
        sortSelect($selectToFilter[0]);
    }

    function sortSelect(selectToSort) {
        var arrOptions = [];

        for (var i = 0; i < selectToSort.options.length; i++)  {
            arrOptions[i] = [];
            arrOptions[i][0] = selectToSort.options[i].value;
            arrOptions[i][1] = selectToSort.options[i].text;
            arrOptions[i][2] = selectToSort.options[i].selected;
        }

        arrOptions.sort();

        for (var i = 0; i < selectToSort.options.length; i++)  {
            selectToSort.options[i].value = arrOptions[i][0];
            selectToSort.options[i].text = arrOptions[i][1];
            selectToSort.options[i].selected = arrOptions[i][2];
        }
    }
});
like image 25
travis Avatar answered Oct 05 '22 16:10

travis