Избегайте такой же опции, выбранной несколько раз, используя jquery

У меня есть две таблицы Table1 и Table2. Каждая таблица содержит тег <select>, а параметры и их значения были одинаковыми.

Теперь я хочу проверить каждую таблицу, существует ли какой-либо вариант более одного раза. Если да, то уже выбран вариант предупреждения.

Мой код:

$('#table1 tr').each(function() {
    $(this).find('select').change(function() { //alert($(this).val())
        if ($('option[value=' + $(this).val() + ']:selected').length > 1) {
            alert('option is already selected');
            $(this).val($(this).find("option:first").val());
        }
    });
});

$('#table2 tr').each(function() {
    $(this).find('select').change(function() { //alert($(this).val())
        if ($('option[value=' + $(this).val() + ']:selected').length > 1) {
            alert('option is already selected');
            $(this).val($(this).find("option:first").val());
        }
    });
});

При выборе этого параметра в первой таблице и во второй таблице он будет отмечать уже выбранный вариант. Что не так с моим кодом?

Вы можете протестировать код здесь.

Ответ 1

Проблема заключалась в том, что вы выбирали все параметры (table1 + 2), тогда как вы должны были выбрать параметры, принадлежащие текущей таблице, например ниже.

$('#table1 tr').each(function() {                                       
    $(this).find('select').change(function(){//alert($(this).val())
        if( $('#table1').find('select option[value='+$(this).val()+']:selected').length>1){
            alert('option is already selected');
            $(this).val($(this).find("option:first").val());   
        }
    });
});

$('#table2 tr').each(function() {                                       
    $(this).find('select').change(function(){//alert($(this).val())
        if($('#table2').find('select option[value='+$(this).val()+']:selected').length>1){
            alert('option is already selected');
            $(this).val($(this).find("option:first").val());   
        }
    });
});

Демо @Fiddle

Edit:

Немного лучшая версия:

// Have a class if you will, for your 2 tables (or more) which would avoid the use of ID as you may not even need them
// <table class="grouped-select" ... >
// and then do:
// $('.grouped-select').find('select').on('change', function() {
// or just use tag selector
$('table').find('select').on('change', function() {
    //Cache jQuery references that you'd reuse over and over
    var $this = $(this);
    if( $this.closest('table').find('select option[value=' + $this.val() + ']:selected').length > 1) {
        alert('option is already selected');
        $this.val($this.find("option:first").val());
    }
});

Ответ 2

Вы выбираете все options вместо текущей таблицы.

Live Demo

Изменить

$('option[value=' + $(this).val() + ']:selected')

Для

$(this).closest('table').find('option[value='+$(this).val()+']:selected')

Вы можете сделать одиночный обработчик вместо нескольких для каждой строки и упростить и оптимизировать код, подобный этому.

$('select').change(function () {
    if ($(this).closest('table').find('option[value=' + $(this).val() + ']:selected').length > 1)
    {
        alert('option is already selected');
        $(this).val($(this).find("option:first").val());
    }
});

Ответ 3

Если вы изменяете свои операторы if, чтобы быть конкретными для каждой таблицы, которая должна это делать. Итак:

if($('#table1 tr option[value='+$(this).val()+']:selected').length>1)

и if($('#table2 tr option[value='+$(this).val()+']:selected').length>1)

и на самом деле, если вы изменили селектор на родительские селектора, вы можете использовать только один кодовый блок любой таблицы такого типа:

$('table').each(function() {
    $(this).find('select').change(function() {

        if ($(this).parent().parent().parent().parent().find($('tr option[value=' + $(this).val() + ']:selected')).length > 1) {
            alert('option is already selected');
            $(this).val($(this).find("option:first").val()); //put it back to 1
        }
    });
});

В этом он просматривает все таблицы, а в событии изменения находит таблицу своей частью (поэтому идентификатор не имеет значения), а затем запускает вашу проверку, как и раньше.

И даже лучше, чем вы могли бы использовать селектор .closest

$('table').each(function() {
    $(this).find('select').change(function() {

        if ($(this).closest('table').find($('tr option[value=' + $(this).val() + ']:selected')).length > 1) {
            alert('option is already selected');
            $(this).val($(this).find("option:first").val()); //put it back to 1
        }
    });
});

Ответ 4

$('#table1 tr').each(function() {
    $(this).find('select').change(function() { //alert($(this).val())
        if ($('#table1 tr td select  option[value=' + $(this).val() + ']:selected').length > 1) {
            alert('option is already selected');
            $(this).val($(this).find("option:first").val());
        }
    });
});

$('#table2 tr').each(function() {
    $(this).find('select').change(function() { //alert($(this).val())
        if ($('#table2 tr td select option[value=' + $(this).val() + ']:selected').length > 1) {
            alert('option is already selected');
            $(this).val($(this).find("option:first").val());
        }
    });
});

Ответ 5

Попробуйте с селектором атрибутов в jquery

$('[id ^= "table"] tr').find('select').change(function() {
    if ($(this).closest('table').find('option[value=' + $(this).val() + ']:selected').length > 1) {
        alert('option is already selected');
        $(this).val($(this).find("option:first").val());
    }
});

Fiddle