backbonejs validation on create - javascript

this is my model
Msg = Backbone.Model.extend({
validate: function(attr){
if(attr.msg === undefined || attr.msg === ''){
return "empty messege";
}
},
initialize: function(){
this.on('invalid',function(model,error){
console.log(error);
});
}
});
and I have collection of Msgs msgCollection
so if I do msgCollection.create({msg:''});
this model gets added to collection
how can I prevent this

For the record!
Pass
{wait:true}
as an option when you call create:
msgCollection.create({msg:''}, {wait:true});

Related

I am unable to execute validation in Backbone.js.

Whenever I set the age attribute to negative value it doesn't return false.
I have also tried executing this code in the console and still nothing happens
<script>
var Human = Backbone.Model.extend({
// If you return a string from the validate function,
// Backbone will throw an error
defaults: {
name: 'Guest user',
age: 23,
occupation: 'worker'
},
validate: function( attributes ){
if( attributes.age < 0){
return "Age must me positive";
}
if( !attributes.name ){
return 'Every person must have a name';
}
},
work: function(){
return this.get('name') + ' is working';
}
});
var human = new Human;
human.set("age", -10);
human.on('error', function(model, error){
console.log(error);
});
</script>
There are a few things wrong with your code:
The event for validation is invalid, error is for ajax requests.
Validation on set doesn't happen by default, you need to pass { validate: true } as an option.
You are listening to the event AFTER setting, so it won't get called for that set.
i.e:
human.on('invalid', function(model, error) {
console.log(error);
});
human.set("age", -10, { validate: true });

Backbone.js manually trigger "error" on a collection

I want my collection to fail if the server/json return a specific STATUS (e.g. no results).
The problem: The default error-handler is not called (cause the collection successfully fetches the json. So my idea is use the parse function to look for an error-code in the json.
But how to I trigger the error-method and notify my view (and stop to collection trying to create models)
/*global define*/
define([
'underscore',
'backbone',
'models/mymodel'
], function (_, Backbone, MyModel) {
'use strict';
var SomeCollection = Backbone.Collection.extend({
model: MyModel,
value: null,
url: function() {
return url: "data/list.json";
},
initialize: function(models, options) {
this.zipcode = options.zipcode;
},
parse: function(response, xhr) {
if(response.status == "OK") {
console.info("Status: "+response.status);
return response.results;
} else {
console.warn("Status: "+response.status+" – Message: "+response.message);
this.trigger('fail') // does not work
return response;
}
}
});
return SomeCollection;
});
I have a post on my blog about this kind of things, unfortunately it's in portuguese, but maybe google translate helps you.
http://www.rcarvalhojs.com/dicas/de/backbone/2014/06/24/gerenciando-o-estado-da-aplicacao.html
I like to handle this, in this way
GetSomething:->
#result = #fetch(
success:()=>
#trigger "succesthing1" if #result .status is 204
#trigger "successThing2" if #result .status is 200
error:()=>
#trigger "errorThing" if #result .status is 401
)
Now i can listen for these trigger inside the view and take the correct action for a specific the result from server
There are currently I subscribe for of the Backbone sync, by sending events according to the promise that the request returned, see example below:
(function(Backbone) {
var methods, _sync;
_sync = Backbone.sync;
methods = {
beforeSend: function() {
return this.trigger("sync:start", this);
},
error: function() {
return this.trigger("sync:error", this);
},
complete: function() {
return this.trigger("sync:stop", this);
}
};
Backbone.sync = function(method, entity, options) {
var sync;
if (options == null) {
options = {};
}
_.defaults(options, {
beforeSend: _.bind(methods.beforeSend, entity),
error: _.bind(methods.error, entity)
complete: _.bind(methods.complete, entity)
});
sync = _sync(method, entity, options);
if (!entity._fetch && method === "read") {
return entity._fetch = sync;
}
};
})(Backbone);
Hope this helps.

Invalid model event is not fired in the ItemView

I have defined the following events in an ItemView:
modelEvents: {
"change": "refresh",
"invalid": "handleValidation"
}
and the validate function in my Model is:
validate: function(attrs) {
if(attrs.Code == "")
return "Error in Code field";
else if(attrs.Name == "")
return "Error in Name field";
}
The problem is that when I save an instance of my model, validate function is called in the model and returns string messages succesfully, but the invalid event in the ItemView is not fired.
Thanks
What you have right now should be working. There must be some disconnect in the code that you've provided. I've create a simple JSFiddle that samples the functionality you're wanting: http://jsfiddle.net/craigjennings11/DZtDm/
var View = Backbone.Marionette.ItemView.extend({
el: '#content',
template: _.template('<button>Hello World</button>'),
events: {
'click button': 'tryToSave'
},
modelEvents: {
'invalid': 'failedValidation'
},
tryToSave: function() {
this.model.save();
},
failedValidation: function(err) {
this.$el.append('<div>' + err.validationError + '</div>');
}
});
You should trigger 'invalid' event and return error meggase as attribute.
validate: function(attrs) {
if(attrs.Code == "")
this.trigger('invalid', 'Error in Code field');
else if(attrs.Name == "")
this.trigger('invalid', 'Error in Name field');
}
Like this.

Updating Model from form in Backbone

I am creating a simple application using Backbone and Laravel to manage bookings, and I'm working on a simple form to update user data for the currently signed in user.
I was wondering, is there a better, more efficient way than the way I have done, to update your model with the input data from the form?
I have created a method called update in the model, which is passed a DOM object of the form. I assume this isn't the best way to go about it.
Any help would be very much appreciated!
var Account = Backbone.Model.extend({
url: "/settings/account",
initialize: function()
{
},
update: function(form)
{
this.set({
first_name : form.find('#first-name').val(),
last_name : form.find('#last-name').val(),
email : form.find('#email').val(),
landline: form.find('#landline').val(),
mobile: form.find('#mobile').val()
});
return this.save();
}
});
var user = new Account;
var AccountView = Backbone.View.extend({
el: $("div.section"),
template: _.template($("#account-template").html()),
events: {
"submit #account": "update"
},
initialize: function()
{
_.bindAll(this, 'render', 'update');
this.render();
},
render: function()
{
$(this.el).html(this.template(this.model.toJSON()));
},
update: function()
{
var form = $(this.el).find('form#account');
user.update(form);
$(this.el).find('.alert-success').show();
return false;
}
});
var Router = Backbone.Router.extend({
routes: {
"account": "account"
},
account: function()
{
user.fetch({
success: function()
{
return new AccountView({model:user});
}
});
}
});
It is considered bad design when the model is aware of its view. I would make the update of the model orchestrated by the view.
I think the easiest way would be to do this in the view:
update: function()
{
var form = $(this.el).find('form#account');
user.set({
first_name : form.find('#first-name').val(),
last_name : form.find('#last-name').val(),
email : form.find('#email').val(),
landline: form.find('#landline').val(),
mobile: form.find('#mobile').val()
});
user.save();
$(this.el).find('.alert-success').show();
return false;
}
Otherwise the model would have to know where to retrieve the values. Also, when you someday use a different view you would also have to change the model class.

Backbone model is kept from changing

My app uses Backbone. It has a model that users can change. This model must be validated before being changed. If it has changed, a function is called. When users click on save, the model is saved if and only if it has changed.
My problem is that when the change event is fired the model has no longer changed, therefore it will not be saved.
Here is the code: http://jsfiddle.net/keepyourweb/jQL8V/
var model = Backbone.Model.extend({
initialize: function() {
},
default: {
'first_name': 'none',
'last_name': 'none'
},
validate: function(attr) {
if (_.isEmpty(attr['first_name'])) return 'Error name required';
}
});
var test = new model,
showError = function(model, error) {
alert(error);
},
changed = function() {
alert('changed!');
};
test.bind('change', changed);
test.set({'first_name': 'test_name', 'last_name': 'test_surname'}, {error: showError});
$('#save').bind('click', function() {
if (test.hasChanged()) alert('Saved!!');
});

Categories