هل هناك أي طريقة لإعادة ملء خيارات Html Select دون إطلاق حدث التغيير (باستخدام jQuery)؟

StackOverflow https://stackoverflow.com/questions/44903

سؤال

لدي عدة اختيارات:

<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>

ما أريده هو تحديد "واحد" من الاختيار الأول، ثم إزالة هذا الخيار من الخيار الثاني.ثم إذا قمت بتحديد "اثنين" من الثاني، أريد إزالة ذلك من الأول.

إليك JS الموجود لدي حاليًا:

$(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();
    });
});

ولكن عندما تتم إعادة ملء العناصر، فإنه يطلق حدث التغيير في التحديد الذي تتغير خياراته.حاولت فقط وضع disabled السمة على الخيار الذي أريد إزالته، ولكن هذا لا يعمل مع IE6.

هل كانت مفيدة؟

المحلول

أنا لست (حاليًا) مستخدمًا لـ jQuery، لكن يمكنني أن أخبرك أنك بحاجة إلى فصل معالج الأحداث مؤقتًا أثناء إعادة ملء العناصر أو، على الأقل، تعيين علامة تختبرها بعد ذلك بناءً على قيمتها، التعامل مع التغيير.

نصائح أخرى

هذا هو الكود النهائي الذي انتهيت من استخدامه، العلم (changeOnce) عملت بشكل رائع، شكرًا @جايسون.

$(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];
        }
    }
});

أو يمكنك فقط إخفاء الخيار الذي لا تريد إظهاره...

function hideSelected($one, $two)
{
    $one.bind('change', function()
    {
        var val = $one.val();
        $two.find('option:not(:visible)').show().end()
            .find('option[value='+val+']').hide().end();
    })
}
hideSelected($one, $two);
hideSelected($two, $one);

يحرر:عفوًا، هذا الرمز لا يعمل مع IE6...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top