15

I'm using the following code to create the view:

LoginForm = Backbone.View.extend({

    tagName :"form"
    ,id : "login-form"
    ,className :"navbar-form"
    ,initialize: function () {
            this.model = new StackMob.User();
            this.render();
    }
    ,render: function () {
            $(this.el).html(this.template());
            return this;
    }
    ,events : {
            "change" : "change"
            ,"submit #login-form" : "login"
    }
    ,login : function( event) {
            event.preventDefault();
            var self = this;
            this.model.login(true, {
                    success: function( model) {
                            app.alertSuccess( "User logged in");
                            self.render();
                    }
                    ,error: function( model, response) {
                            app.alertError("Could not login  user: " + response.error_description);
                    }
            });
            event.currentTarget.checkValidity();
            return false;
    }
// rest of code

And the template:

<input name="username" class="span2" type="email" placeholder="Email" required >
<input name="password" class="span2" type="password" placeholder="Password" required >
<button id="login-button" type="submit" class="btn">Sign in</button>

When I bind on the button, the login function gets called. Binding on the form submit event, the login function does not get called. I can also get the form to bind if the id & form tag are part of the template, which is not what I want to do here.

How do I bind on the form submit in this case?

Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
Jim Barrows
  • 3,634
  • 1
  • 25
  • 36

3 Answers3

37
"submit #login-form" : "login"

I think Backbone will search for this id among the descendants only. So it will never match your own view element. Why don't you just use:

"submit": "login"

As you did for change.
Gonna check Backbone's code just to be sure.

Edit:
If you put a selector, Backbone will call

this.$el.on(event, selector, method);

instead of

this.$el.on(event, method);

And the on method of jQuery will instead apply the selector to the descendants of the element only, excluding the element itself.

fubar
  • 16,918
  • 4
  • 37
  • 43
Loamhoof
  • 8,293
  • 27
  • 30
  • 3
    The relevant documentation is hidden inside the [`delegateEvents`](http://backbonejs.org/#View-delegateEvents) documentation: "Omitting the `selector` causes the event to be bound to the view's root element `(this.el)`." – mu is too short Mar 28 '13 at 15:50
  • Unfortunately this doesn't exclude what he was doing. Well, I guess it's still enough information. – Loamhoof Mar 28 '13 at 15:52
  • I would hope everyone would [read my answer](http://stackoverflow.com/a/29465198/124486), because this is waaaackk advice. – Evan Carroll Apr 06 '15 at 04:18
3

You're using Backbone wrong. So what you're going to want to do,

template: my_template_string,
render: function () {
    this.el.innerHTML = this.template();
},
events: {
    "submit #login-form": function (event) {}
}

Where this.template is set to

<form id="login-form" class="navbar-form">
    <input name="username" class="span2" type="email" placeholder="Email" required >
    <input name="password" class="span2" type="password" placeholder="Password" required >
    <button id="login-button" type="submit" class="btn">Sign in</button>
</form>

And doesn't that only make sense? Why would you want the id and classname to be separated from the input elements? BTW, you can still do the naked catchall on submit, but only in my method will,

  • the <form> class, and <form> attribute be tied to the form's template, and not just the backbone view,
  • will you be explicitly capturing the right submit,
  • can you ever support multiple submit events (in the event one template has two forms).
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
  • You are talking about "zombie views" issue? id/tagName ain't related to the issue at all. – suish Apr 06 '15 at 04:47
  • @suish yea, I agree my reason for not using tagname, and className, id is slightly different. I was serving them on the page and not letting Backbone create them. I've removed my rants about that and left the other more applicable parts of the answer. I still advice never using that functionality. ;) – Evan Carroll Apr 06 '15 at 06:54
0

Maybe When you bind on the form submit event, it is only submit the form will fire the 'submit' event. you could add below code and try it again.

$('#id').submit(function(ev) {

});
Courage
  • 543
  • 5
  • 25