0

I am having problems getting my backbone.js view events to fire. When I click #login-button nothing is happening.

I am also using iCanHaz (http://icanhazjs.com/) to load the templates.

Here is my javascript:

$(function() {
 var router = new App.Router;
 Backbone.history.start();
});

App.Router = Backbone.Router.extend({
 routes: {
    "login": "login"
 },

login: function() {
    var view = new App.Views.LoginView;
 }
});

App.Views.LoginView = Backbone.View.extend({

 el: '#login',

 initialize: function() {

    _.bindAll(this, 'render', 'validateLogin');
    this.render();

 },

 render: function() {
    App.Stage.html(ich.loginView());
 },

 events: {
    'click button#login-button' : 'validateLogin'
 },

 validateLogin: function(event) {
     console.log("validateLogin fired.");
 }

});

Here is my markup (using ICanHaz.js):

<script id="loginView" type="text/html">
        <div data-role="page" id="login" class="container">
            <div class="hero-unit">
                <div class="row-fluid">
                    <div class="span12">
                        <div class="form-horizontal">
                        <fieldset>
                            <legend>Please login to continue</legend>
                            <div class="control-group">
                            <label class="control-label" for="username">Username</label>
                            <div class="controls">
                                <input type="text" class="input-xlarge" id="username">
                            </div>
                            </div>

                                <div class="control-group">
                            <label class="control-label" for="password">Password</label>
                            <div class="controls">
                                <input type="password" class="input-xlarge" id="password">
                            </div>
                            </div>

                                <div class="form-actions">
                        <button id="login-button" class="btn btn-primary btn-large">Login</button>
                    </div>
                        </fieldset>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </script>
Dustin
  • 8,217
  • 11
  • 33
  • 44
  • 1
    Is your login view template actually rendering to the screen? – Paul Apr 02 '12 at 21:14
  • Yes, everything is working as expected with no console errors. I click the button and the event is not triggered though. – Dustin Apr 02 '12 at 22:26

2 Answers2

4

I figured it out. Backbone was binding the events to the el before it was created. In the callback for the asynchronous iCanHaz call, I used this.setElement('#login') and it worked perfectly. From the backbone.js documentation:

setElement [view.setElement(element)]

"If you'd like to apply a Backbone view to a different DOM element, use setElement, which will also create the cached $el reference and move the view's delegated events from the old element to the new one."

Dustin
  • 8,217
  • 11
  • 33
  • 44
-1

I believe you aren't using the View's 'el' property correctly. Try having the property reference the jQuery DOM object instead of just the ID, as follows:

App.Views.LoginView = Backbone.View.extend({

 el: $('#login')

...
Whoa
  • 1,334
  • 11
  • 26
  • No luck. I also tried setting it in my router like this `login: function() { if (App.User.isLoggedIn) { window.location.hash = 'home'; } else { var view = new App.Views.LoginView({ el: $('#login') }); } }` and both times the event did not fire and console.log(this.el) was undefined. – Dustin Apr 03 '12 at 00:07
  • Oh, I missed this before, hopefully it's it: When you create the new login view, you've got to call it as it is (a function, not a property). Try: var view = new App.Views.LoginView(); – Whoa Apr 03 '12 at 02:50