NotGaeL
NotGaeL

Reputation: 8484

get the value and status (selected or not) of the option that triggers a multiple select onchange event

I want to get only the value added/removed from the selection instead of an array with all the selected values.

How can I monitor each individual option instead of the whole selector to see which one has changed?

I know I can compare the previous and current state of the whole selector, but that means saving the previous state, and since it is not just one selector I want to keep track of but an undetermined number of them (one per record on a list of records retrieved from the database), I would very much rather use a simpler way to get the last selected/unselected value if there is one.

Another alternative I just thought of: Instead of keeping track of every selector state, using the onfocus event to save the state of the selector about to be modified (but still, I would prefer a solution where I do not have to compare states, if there is one).

Current solution: use bootstrap multiselect jquery plugin's onchange option (bootstrap multiselect turns the selector into a list so each option can be monitored individually using its own onchange event). Any "pluginless" ideas?

Upvotes: 3

Views: 162

Answers (1)

nrodic
nrodic

Reputation: 3021

I don't think there exists some decent solution. Roll your own jQuery plugin to abstract state comparison.

Maybe this little plugin which triggers custom optionChange event on list, providing two additional parameters (value, state) can help you:

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

If needed, you can modify it to trigger single event with list of removed options.

Upvotes: 1

Related Questions