I am doing a simple validation for my username and password. My Model is here:
define(["backbone"], function(Backbone){
var LoginModel = Backbone.Model.extend({
url:'/home',
defaults:{
userName:'',
password:''
},
initialize:function(){
this.bind("change", this.attributesChanged);
},
validate:function(attrs){
var errors = [];
if(attrs.userName < 5){
errors.push({"name": 'userName', "message": 'Please fill email field.'});
}
if(!attrs.password){
errors.push({"name": 'password', "message": 'Please fill feedback field.'});
}
return errors.length > 0 ? errors : false;
},
attributesChanged : function(){
var valid = false;
if (this.get('userName') && this.get('password')) {
valid = true;
this.trigger("validated", valid);
}
else {
this.trigger('invalid', valid); //triggers the invalid works fine.
}
}
});
return LoginModel;
});
But in the view, I am still getting that trigger, but I am not able to get the view's element to highlight the inputs:
here is my view:
define([
'jQuery','underscore',
'backbone','marionette',
'text!./templates/loginView.html'],
function($,_,Backbone,Marionette,template){
"use strict";
var LoginView = Backbone.Marionette.ItemView.extend({
className:'col-xs-12 col-md-4 col-md-offset-4',
template:_.template(template),
events:{
"submit form" : "loginSubmit"
},
initialize:function(params){
this.model.view = this;
this.model.bind("validated", this.validated);
this.model.bind("invalid", this.showErrors);
},
loginSubmit:function(e){
e.preventDefault();
var form = e.target,
data = Backbone.Syphon.serialize(form);
var that = this;
var options = {
success: function (model,response) {
if(response){
console.log('success', response)
} else {
console.log('failed')
}
},
error: function(model, options){
console.log("error", xhr.responseText);
}
};
this.model.save(data, options);
// this.model.on('invalid', function(model, error) { console.log(model,'\n', error); })
},
validated:function(value){
console.log(value);
},
showErrors:function(model, error){
var form = this.$el.find('form'); // i am not able to get form element here... what is the issue?
_.each(error, function(value, key){
var input = form.find('input[name='+value.name+']').addClass('error');
input.after('<span class="errorMsg">'+value.message+'</span>');
});
},
hideErrors:function(msg){
console.log('login success!');
},
onShow:function(){
$('input:text').first().select();
}
});
return LoginView;
}
);
And I am confused in this parts, any help me to uderstand:
1) How to differenciate whether the error from 'validate' method or 'server'
2) How to handle this both properly?
3) what is the correct approach that, what i posted here?
I am not so experienced in this areas, any expert can help me to proceed my app dev?
don't direct my to some books, i came across please help me to learn from my code. thanks in advance!
I'm going to answer your questions below:
invalid
event is triggered from validate
(which you may want to consider using since you can validate on set
of properties). the error
event is triggered when the response comes from the server.validate
will not send information to the server. You should use that if that's the response you're looking for.Here's how to fix your reference problem:
Instead of this in your view's initialize
:
initialize:function(params){
this.model.view = this;
this.model.bind("validated", this.validated);
this.model.bind("invalid", this.showErrors);
}
You should do:
initialize:function(params){
this.model.view = this;
this.listenTo(this.model, "validated", this.validated);
this.listenTo(this.model, "invalid", this.showErrors);
}
which ensures that when the view is closed, the events will be removed. It also makes sure that the this
in your methods refers to your view. Right now, it refers to your model.
Also, just an aside, if you want to find
a selector within your view, there's a shortcut – this.$
– which is the same as this.$el.find
.