Reputation: 8139
I have a Backbone View which handles a registration component, because this required a lot of form access I had the idea to store the form selectors in an object property.
define(["models/security/user", 'text!templates/security/registration.html'], function(SecurityUserModel, Template){
var SecurityRegistrationView;
SecurityRegistrationView = Backbone.View.extend({
initialize: function(){
this.model = new SecurityUserModel();
this.model.bind("validated:valid", this.valid);
this.model.bind("validated:invalid", this.invalid);
Backbone.Validation.bind(this);
this.render();
},
render: function(){
$(this.el).append(Template);
},
events: {
"submit form": "submit"
},
form: {
"username": $("#_user_username")
, "email": $("#_user_email")
, "password": $("#_user_password")
},
submit: function(e){
e.preventDefault();
this.model.set("username", this.form.username.val());
this.model.set("password", this.form.email.val());
this.model.set("email", this.form.password.val());
this.model.validate();
// debug
console.log([this.form, this.form.username.val(), this.form.email.val()]);
if (this.model.isValid) {
this.model.save();
}
},
valid: function(model, attrs){
// error
this.form.attrs[0].username.parent("div.control-group").addClass("success");
},
invalid: function(model, attrs){
// error
this.form.attrs[0].username.parent("div.control-group").addClass("error");
}
});
return SecurityRegistrationView;
});
When I console.log this.form, I get an object which looks quite good nothing undefined or weird:
[
Object
email: e.fn.e.init[0]
context: HTMLDocument
selector: "#_user_email"
__proto__: Object[0]
password: e.fn.e.init[0]
context: HTMLDocument
selector: "#_user_password"
__proto__: Object[0]
username: e.fn.e.init[0]
context: HTMLDocument
selector: "#_user_username"
__proto__: Object[0]
__proto__: Object
]
Loggin an jquery function accessing the selectors (this.form.username.val()) fails with undefined.
Why can't use jQuery functions on properties ($el uses this to) where is the thinking error?
Upvotes: 3
Views: 3439
Reputation: 6552
You are not using the selector in the right way. You need to scope your jQuery to your view doing this:
invalidateForm: {
"username": this.$("#_user_username"),
"email": this.$("#_user_email"),
"password": this.$("#_user_password")
},
And render must be in this way:
render: function(){
this.$el.append(Template);
this.invalidateForm();
},
Also use this.$el instead of $(this.el) to have more efficient performance, it is a cached version of the view element.
Upvotes: 2
Reputation: 638
it's a context problem,you can update you code like this:
initialize: function(){
_.bindAll(this, 'render', 'submit', 'valid','invalid');
this.model = new SecurityUserModel();
.....
}
about _.bindAll ,you can see this: Does backbone do _.bindAll by default now? https://stackoverflow.com/a/6396224/1303663
EDIT:>>>>>>>>>>>>
Sorry, I did not fully understand what you mean. you can try this,I think this is what you want:
render: function(){
$(this.el).append(Template);
this.initform();
},
.....
initform: function(){
this.form = {};
this.form.username = $("#_user_username");
this.form.email = $("#_user_email");
this.form.password = $("#_user_password");
},
No other changes
Upvotes: 1
Reputation: 15422
I think the problem is, form: {...}
is evaluated before render
is called -- and the HTML elements you query are created in render
.
Maybe you can try to do this at the end inside the render function:
this.form = {
"username": $("#_user_username")
, "email": $("#_user_email")
, "password": $("#_user_password")
}
Upvotes: 2