Question

I have a select multiple choice (like this one) and I don't know how to make an event in BackboneJS that detects when the select gets or loses items.

Initially I did something like this:

var view = new Backbone.View.extend({
    initialize : function() {
        ...
    },
    events : {
        "change select" : "changed"
    }
});

But this example, the only that detects it's about item selected, not item added or deleted.

Any idea? Thanks.

Was it helpful?

Solution

There are DOM mutation events but they've been deprecated:

Deprecated
This feature has been removed from the Web. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.

The mutation events have been replaced with MutationObservers but you might have browser compatibility problems if you try to use them.

All that is moot though; if you structure your view so that the #add and #remove buttons are inside the view then you can use simple (and reliable and supported everywhere) Backbone view events to handle everything. Something like this:

<div id="container">
    <select id="select_1" ...>
    <input id="add" ...>
    <input id="remove" ...>
    <select id="select_2" ...>
</div>

and then in your view:

Backbone.View.extend({
    el: '#container',
    events: {
        'click #add': 'add',
        'click #remove': 'remove'
    },
    add: function() {
        var opt = this.$('#select_1 option:selected').clone();
        this.$('#select_2').append(opt);
    },
    remove: function() {
        this.$('#select_2 option:selected').remove();
    }
});

Note the use of this.$ in the view, this.$(x) in a view is the same as this.$el.find(x); that isn't strictly necessary but it is a good habit to keep your view from messing with things that it doesn't own.

If your view needs to do more things when adding a new entry to the second list or removing an entry from the second list then you can put those things inside the add and remove methods. If someone else needs to know then you can:

  1. Trigger events on he view and let other parts of the app listen for those events.
  2. Trigger events though a global event bus and let other parts of the app list to the event bus.
  3. Apply changes to the view's collection or model and let other parts of the application listen for events from that collection or model.

Demo: http://jsfiddle.net/ambiguous/uAHL3/1/

OTHER TIPS

You can try listen for DOMNodeInserted and DOMNodeRemoved events

$('#select_2').on('DOMNodeInserted', function (e) {alert('node added')});
$('#select_2').on('DOMNodeRemoved', function (e) {alert('node removed')});

Example -> jsfiddle

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top