I'm trying to create a backbone model using:
var newUser = new App.User({
name: $('input[name=new_user_name]').val(),
email: $('input[name=new_user_email]').val()
});
with the following validation:
App.User = Backbone.Model.extend({
validate: function(attrs) {
errors = [];
if (_.isEmpty(attrs.name)) {
errors.push("Name can't be blank");
}
if (_.isEmpty(attrs.email)) {
errors.push("Email can't be blank");
}
return _.any(errors) ? errors : null;
},
...
});
However, when the textbox values are empty, the model can't be created because the validations fail.
Is there a way to create a model and run isValid()
to check the values are correct? Or is there some other way to run validations before the model is created?
From the backbone model creation code, it appears it throws the exception Error("Can't create an invalid model")
upon failing validation, but would it be possible to check validations before hand?
You can create unvalid model with silent: true
, but in this way collection don`t trow event 'add'. But you can sent default option to function add and catch this option in validate()
collection.add({option:'unvalid_value'}, {validation: false});
Model = Backbone.Model.extend({
validate: function(attributes, options){
if (options.validation === false)
return;
//Validation code
//.....
}
});
This way you can create model with invalid hash)
My understanding is that you want to create a user model and that model gets populated with attributes based on some form input.
The way you have it set up now, to me doesn't seem very backbone-y.
var newUser = new App.User({
name: $('input[name=new_user_name]').val(),
email: $('input[name=new_user_email]').val()
});
To me it feels like you're mixing up stuff that happens in your views with your model which is the object it should represent. I would probably create a basic blank Model first, then a View that compliments this model and pass the model in.
User = Backbone.Model.extend ({
defaults: {
name: undefined,
email: undefined
}
)};
UserView = Backbone.View.extend ({
events: {
// like click on submit link, etc.
'click #submitButton': 'onSubmit'
},
initialize: function() {
this.user = this.model;
},
onSubmit: function() {
// run some validation on form inputs, ex. look for blanks, then...
if ( /* validation passes */ ) {
var nameEntered = $('input[name=new_user_name]').val();
var emailEntered = $('input[name=new_user_email]').val();
this.user.set({name:nameEntered, email:nameEntered});
}
}
});
// Do it!
var newUser = new User();
var newUserView = new UserView({model:newUser});
One great way to validate the form INPUT rather than than the Model attributes is to use jquerytools validator. It works with HTML5 attributes such as pattern=regex and type=email and makes it super easy.
You cannot create an Invalid model in backbone.
If you are creating a model and passing values to the constructor the no validation will be done.
If you are adding models to a collection via fetch then invalid data will cause the model validation to fail and the model will not be added to the collection. This should trigger the error
event so you should be listening for it in case your server is providing invalid data back.
If you want to make a model but make sure the data is valid you must:
var mymodel = new MyModel();
mymodel.set(attrs);
Even if you try to pass {silent: false}
during model instantation backbone will override it since it will not let you create an invalid model and does not throw errors. (which we arent discussing here)
You can see this by looking at the source, but also look at this github ticket