Backbone.Validation Checklist for troubleshooting validation not working
Client-side javascript validation using Backbone.Validation
Troubleshooting Checklist
(1) Make sure backbone.validation.js and backbone.validation.bootstrap.js are included.
backbone.validation.js : https://github.com/thedersen/backbone.validation/blob/master/src/backbone-validation.js
backbone.validation.boostrap.js : https://gist.github.com/driehle/2909552
(2) Make sure your model extends Backbone.Model() and add a validation object to your model after the default declaration :
SuperApp.Model = Backbone.Model.extend({
defaults : {
...
},
validation: {
"songTitle": {
required: true,
msg: "Please provide a song title"
}
}
});
(3) Add this to your view afterRender() or custom after-render function :
afterRender: function() {
Backbone.Validation.bind(this);
}
(4) Add validate:true when you set your values to trigger instant validation :
Example #1:
this.model.set({
songTitle: newSongTitle
}, {validate: true});
if (this.model.isValid() === false)
{
// fields have been colored red.
}
Example #2:
var promise = this.model.save({}, {success: function(...){...}, error: function(...){...}});
if (promise === false)
{
// fields have been colored red.
}
(5) In order for the validation code to automatically highlight red your fields and display the message you need your HTML to follow these guidelines :
- Each field be contained within a <div> which will receive an error class
- Have the input field use the name attribute that matches exactly the model variable name : the backbone validator bootstrap needs this, for example <input type="text" name="songTitle" id="xyx />
Usage examples
validation : {
newPassword: function(value, name, model)
{
if (model.newPassword !== model.newPassword2)
{ return "Passwords do not match";
}
}
},
Full documentation : http://thedersen.com/projects/backbone-validation/
Additionnal troubleshooting
Put a breakpoint at backbone.validation.js, around line 110 or 117 :
var attrValidationSet = model.validation ? _.result(model, 'validation')[attr] || {} : {};
This is where it matches each of your variable with the validation rules.
And also put a breakpoint in the valid: and invalid: functions of backbone.validation.bootstrap.js (if you are using it).
invalid: function(view, attr, error, selector) {
Or another handy place to put a breakpoint is at line 190 in backbone.validation.js :
error = validateAttr(model, attr, val, computed);
if (error) {
invalidAttrs[attr] = error;
isValid = false;
I have come across two reason where the error was not rendered and invalid was correctly triggered : One was that there was no <div> surrouning the <input> field to receive the class. The other one was that it was receiving the error, and if you would put a breakpoint and step through the invalid function, you would see it appear, and then if you hit F5 to continue the execution it would clear itself meaning it was only temporarily drawn and then reset back right after. It was because I was calling model.set{(...), {validate:true}) which was doing the first validation, and later doing model.save(null, {...}) to sync it with the server which was triggering a second validation on a null object. The solution was to simply pass validate:false in the model.save() like this :
this.model.set({
"password": oldPassword,
"newPassword": newPassword,
"newPassword2": newPassword2
}, {validate:true});
var updatePromise = this.model.save(null, {
wait: true,
contentType: "application/json",
error:api.error(function(xhr, status, error) {
}),
success: function(model, response, options) {
notifier.info("Success changing password");
}
});
Recent Comments