Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery & Backbone click events not firing

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(?).

like image 923
SamV Avatar asked Mar 01 '13 13:03

SamV


People also ask

What is jQuery is used for?

jQuery is the most popular library on the web today. It's a library of JavaScript functions that make it easy for webpage developers to do common tasks-- like manipulating the webpage, responding to user events, getting data from their servers, building effects and animations, and much more.

Is jQuery better than JavaScript?

Though JavaScript is the basic language from which jQuery has evolved, jQuery makes event handling, DOM manipulation, Ajax calls much easier than JavaScript. jQuery also allows us to add animated effects on our web page which takes a lot of pain and lines of code with JavaScript.

Is jQuery a JavaScript?

jQuery is a JavaScript Library. jQuery greatly simplifies JavaScript programming.

Is jQuery used in 2022?

But the current projects of web developers don't tell the whole story. Based on BuiltWith's Internet technology trends, jQuery was found on more than 80 million websites in 2022. That's a huge lead over the nearly 11 million websites running React.


2 Answers

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});      
});
like image 107
jevakallio Avatar answered Oct 18 '22 22:10

jevakallio


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

like image 43
webninjataylor Avatar answered Oct 18 '22 22:10

webninjataylor