получить значение и статус (выбрано или нет) параметра, который запускает событие множественного выбора onchange

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

Как я могу отслеживать каждую отдельную опцию, а не весь селектор, чтобы увидеть, какой из них изменился?

Я знаю, что могу сравнить предыдущее и текущее состояние всего селектора, но это означает сохранение предыдущего состояния, и, поскольку я хочу отслеживать не один селектор, а неопределенное их количество (по одному на запись в списке записей, извлеченных из базы данных), я бы предпочел использовать более простой способ получить последнее выбранное/невыбранное значение, если оно есть.

Еще одна альтернатива, о которой я только что подумал: вместо того, чтобы отслеживать каждое состояние селектора, используйте событие onfocus для сохранения состояния селектора, который должен быть изменен (но все же я бы предпочел решение, в котором мне не нужно сравнивать состояния, если есть один).

Текущее решение: используйте опцию onchange плагина jquery bootstrap multiselect (мультиселектор начальной загрузки переключает селектор в список, чтобы каждый параметр можно было отслеживать отдельно, используя собственное событие onchange). Есть идеи "без плагинов"?


person NotGaeL    schedule 02.08.2015    source источник


Ответы (1)


Я не думаю, что существует какое-то достойное решение. Сверните свой собственный плагин jQuery для абстрактного сравнения состояний.

Возможно, вам поможет этот небольшой плагин, который запускает пользовательское событие optionChange в списке, предоставляя два дополнительных параметра (значение, состояние):

$.fn.trackOptions = function(){
    return this.each(function(){
        var $select = $(this),
            oldItems = $select.val() || [];
        $select.data("oldItems", oldItems)
        .on("change", function(e){
            var oldItems = $select.data("oldItems"),
                newItems = $select.val() || [];
            for(var i=0; i<oldItems.length; ++i) {
                if(newItems.indexOf(oldItems[i]) == -1){
                    $select.trigger("optionChange", [oldItems[i], false]);
                }
            }
            for(i=0; i<newItems.length; ++i){
                if(oldItems.indexOf(newItems[i]) == -1){
                    $select.trigger("optionChange", [newItems[i], true]);
                }
            }
            $select.data("oldItems", newItems);
        });
    });
}

jsFiddle

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

person nrodic    schedule 02.08.2015
comment
блестяще! Он обеспечивает именно ту функциональность, которая мне нужна, без добавления узлов списка в DOM или загрузки гораздо большего плагина. Спасибо! - person NotGaeL; 03.08.2015
comment
Рад, что смог помочь. Обратите внимание, что Array.prototype.indexOf недоступен в IE8, поэтому, если вы ориентируетесь на старые браузеры, я предлагаю вам включить полифилл с этой страницы. - person nrodic; 03.08.2015
comment
не тот случай, но спасибо за голову. все равно сделаю :-) - person NotGaeL; 03.08.2015