Dan-Nolan
Dan-Nolan

Reputation: 6657

Backbone JS event on document click

I'm new to working with Backbone JS and I'm creating a Backbone View. I made this View so when you click the template it calls function highlight to add the highlight class to my element:

var PlayerView = Backbone.View.extend({

    // ...

    events: {
        "click .player": "highlight"
    },

    // ...

    highlight: function () {
        this.$el.find('.player').addClass('highlight');
    }

});

I want to make it so when I click anywhere else in the application, I remove the highlight class from this element.

I could declare a click handler on the document and remove the highlight class from there:

$(document).click(function () {
    $('.player.highlight').removeClass('highlight');
});

And then use event.stopPropagation() in the highlight function to prevent bubbling:

var PlayerView = Backbone.View.extend({

    // ...

    highlight: function (evt) {
        evt.stopPropagation();
        this.$el.find('.player').addClass('highlight');
    }
});

This works and exhibits the functionality I'm looking for. However this doesn't exactly leverage the backbone framework. Is there a proper way of doing this in Backbone JS?

Upvotes: 4

Views: 2110

Answers (2)

zloctb
zloctb

Reputation: 11194

   $(document).on('click', function(e){
        Backbone.trigger('document-click-event', e);
    });


var Popup = Marionette.CompositeView.extend({
   ........
    initialize: function(options) {
      _.extend(this, options);
      this.listenTo(Backbone, 'document-click-event', function(e) {
         if (!$(e.target).closest(this.el).length && !$(e.target).closest(this.field).length && !$(e.target).closest('.ui-datepicker').length) {
            this.hide();
         }
      }, this)
.....

Upvotes: 0

damienc88
damienc88

Reputation: 1977

A Backbone View's events hash only looks at things within that view's $el.

If you want to remove the highlight of a player when another player is clicked, you can have your player views rendered within a player collection view, which can watch for click events. You could then:

handleClick: function(e) { 
    this.$(".player").removeClass('highlight');
    this.$(e.currentTarget).addClass('highlight');
}

If you want to handle all clicks regardless of whether they occur within a Backbone.View's $el, then you probably do want to use a global handler.

Note, untested.

If you post details of the structure of your application perhaps a better solution could be suggested.

Upvotes: 1

Related Questions