jQuery & Backbone click events not firing

18,339

Solution 1

You're setting your View element like this:

var LoginView = Backbone.View.extend({
  initialize: function() {
    this.el = $('#login-container');
  }
});

Every Backbone view gets a detached DOM node as its el upon creation. When you set this.el like this, Backbone is not aware that you've changed the element, and is still listening to events on the original, detached node.

Try declaring an el property on the view instead. This is the correct way to bind the view to a pre-existing element:

var LoginView = Backbone.View.extend({
  el: "#login-container",
});

If you need to set a view's el dynamically during the view's lifetime, you should use view.setElement, which enables Backbone to bind the events to the new element:

var LoginView = Backbone.View.extend({
  initialize: function() {
    this.setElement($('#login-container'));
  }
});

Edit based on comments: Sounds like you're trying to initialize the view before your page is fully loaded. Backbone doesn't find the #login-container element, ergo doesn't bind the events. You can verify this with your fiddle too: change the onLoad setting to No wrap <in head> in the fiddle settings, and lo and behold, no events are handled.

You should only initialize your app after the DOM is ready:

$(document).on('ready', function() {
  var newLogin = new Login();
  var loginView = new LoginView({model: newLogin});      
});

Or shortcut for the same:

$(function() {
  var newLogin = new Login();
  var loginView = new LoginView({model: newLogin});      
});

Solution 2

I had to set el without jQuery for it to work in JSFiddle... el: 'body'

Solution 3

As explained by other answer, for events to work you need to use el property. el property is necessary to backbone on registering events by referencing the element in el property. But in some cases, the html is not yet generated. In those cases, you can use tagName instead of el. tagName is useful to generate element dynamically just like document.createElement.

Share:
18,339
SamV
Author by

SamV

https://www.procuro.io https://www.rentivo.com

Updated on June 03, 2022

Comments

  • SamV
    SamV almost 2 years

    I know this problem comes up a million times, but I've been through the answers and none of them help.

    JS Fiddle: http://jsfiddle.net/ZrYYy/

    var LoginView = Backbone.View.extend({
    
        initialize: function () {
    
            console.log('Login View Intialized');
            this.el = $('#login-container');
    
        },
    
        // Setup the events (mainly the login)
        events: {
    
            // Login - function
            "click #login-btn" : "checkLogin"
    
        },
    
        // Actually authorization function
        checkLogin: function() {
    
            console.log("Authorizing login details with server...");
    
        }
    
    });
    
    // Get it all up and going
    var newLogin = new Login();
    var loginView = new LoginView({model: newLogin});
    

    In the fiddle, when I bind a normal $('#login-btn').click(); event it works fine although it does not in my own setup (with chrome). The backbone click event does not work whatsoever.

    This is what the header looks like on my own code

    <link href="assets/admin/css/bootstrap.css" rel="stylesheet" type="text/css">
    <link href="assets/admin/css/bootstrap-responsive.css" rel="stylesheet" type="text/css">
    <link href="assets/admin/css/style.css" rel="stylesheet" type="text/css">
    <script src="assets/admin/js/jquery-1.9.1.min.js"></script>
    <script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
    <script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
    <script src="assets/admin/backbone/login.js"></script>
    <script src="assets/admin/js/bootstrap.min.js"></script>
    

    I know its best practice to include these in the footer but for now whilst this problem exists it doesn't matter(?).

  • SamV
    SamV about 11 years
    That works for the JSFiddle, but not for my local code.. This is getting annoying. jQuery click events don't work on local either at all, I think this is the problem?
  • SamV
    SamV about 11 years
    Gah, I tried both these things separately but never together, thanks!
  • Nothing
    Nothing about 10 years
    @SamV : Can we initialize the view in router in stead of in document.ready ?
  • SamV
    SamV about 10 years
    @Domo I don't know, I use Angular now never got into backbone! Open a new question or google :)
  • Nothing
    Nothing about 10 years
    @SamV That's ok dear. Thanks.
  • DaveWoodall.com
    DaveWoodall.com about 7 years
    The best part of learning Backbone.js in 2017 is that every problem I have has been solved by you awesome 2013 developers. Thank you, from the future.