Giter Club home page Giter Club logo

backbone.validation's Introduction

Backbone.Validation

Version Downlodas Dependencies license Gitter

A validation plugin for Backbone.js that validates both your model as well as form input.

Introduction

Good client side validation is an important part of giving your users a great experience when they visit your site. Backbone provides a validate method, but it is left undefined and it is up to you to override it with your custom validation logic. Too many times I have seen validation implemented as lots of nested ifs and elses. This quickly becomes a big mess. One other thing is that with libraries like Backbone, you hold your state in a Model, and don't tie it to the DOM. Still, when validating your models you probably want to inform your users about errors etc., which means modifying the DOM.

Backbone.Validation tries to solve both these problems. It gives you a simple, extensible way of declaring validation rules on your model, and overrides Backbone's validate method behind the scene. And, it gives you a nice hook where you can implement your own way of showing the error messages to your user.

If you are using node.js on the server you can also reuse your models and validation on the server side. How cool is that?

Backbone.Validation is a bit opinionated, meaning that you have to follow some conventions in order for it to work properly.

Download and source code

You can download the raw source from GitHub, see the annotated source or use the links below for the latest stable version.

Standard builds

AMD builds

Node.js builds

npm install backbone-validation

Bower builds

bower install backbone-validation

Getting started

It's easy to get up and running. You only need to have Backbone (including underscore.js) in your page before including the Backbone.Validation plugin. If you are using the default implementation of the callbacks, you also need to include jQuery.

The plugin is tested with, and should work with the following versions of

  • Backbone >= 1.0.0
  • Underscore >= 1.4.3

Configure validation rules on the Model

To configure your validation rules, simply add a validation property with a property for each attribute you want to validate on your model. The validation rules can either be an object with one of the built-in validators or a combination of two or more of them, or a function where you implement your own custom validation logic.

Validating complex objects is also supported. To configure validation rules for objects, use dot notation in the name of the attribute, e.g 'address.street'.

Example

var SomeModel = Backbone.Model.extend({
  validation: {
    name: {
      required: true
    },
    'address.street': {
      required: true
    },
    'address.zip': {
      length: 4
    },
    age: {
      range: [1, 80]
    },
    email: {
      pattern: 'email'
    },
    someAttribute: function(value) {
      if(value !== 'somevalue') {
        return 'Error message';
      }
    }
  }
});

// validation attribute can also be defined as a function returning a hash
var SomeModel = Backbone.Model.extend({
  validation: function() {
    return {
      name: {
        required: true
      }
    }
  }
});

See the built-in validators section for a list of the validators and patterns that you can use.

Specifying error messages

Backbone.Validation comes with a set of default error messages. If you don't like to use those, you can either override them, or you can specify error messages where you declare validation rules on the model.

You can specify an error message per attribute by adding a msg property like this:

MyModel = Backbone.Model.extend({
  validation: {
    email: {
      required: true,
      pattern: 'email',
      msg: 'Please enter a valid email'
    }
  }
});

Or, you can specify an error message per validator, by adding an array of validators like this:

MyModel = Backbone.Model.extend({
  validation: {
    email: [{
      required: true,
      msg: 'Please enter an email address'
    },{
      pattern: 'email',
      msg: 'Please enter a valid email'
    }]
  }
});

The msg property can also be a function returning a string.

Using form+model validation

The philosophy behind this way of using the plugin, is that you should be able to reuse your validation rules both to validate your model and to validate form input, as well as providing a simple way of notifying users about errors when they are populating forms.

Note that Backbone.Validation does not provide any automatic/two-way binding between your model and the view, that's up you to implement (you can for instance use Backbone.stickit).

Before you can start using form validation, you need to bind your view.

Validation binding

The validation binding code is executed with a call to Backbone.Validation.bind(view). There are several places that it can be called from, depending on your circumstances, but it must be called after your model or collection has been initialized.

// Binding when rendering
var SomeView = Backbone.View.extend({
  render: function(){
    Backbone.Validation.bind(this);
  }
});

// Binding when initializing
var SomeView = Backbone.View.extend({
  initialize: function(){
    Backbone.Validation.bind(this);
  }
});

// Binding from outside a view
var SomeView = Backbone.View.extend({
});
var someView = new SomeView({model: new SomeModel()});
Backbone.Validation.bind(someView);

// Binding to a view with an optional model
var myModel = new Backbone.Model();
var SomeView = Backbone.View.extend({
  initialize: function(){
    Backbone.Validation.bind(this, {
      model: myModel
    });
  }
});

// Binding to a view with an optional collection
var myCollection = new Backbone.Collection();
var SomeView = Backbone.View.extend({
  initialize: function(){
    Backbone.Validation.bind(this, {
      collection: myCollection
    });
  }
});

Binding to view with a model

For this to work, your view must have an instance property named model that holds your model before you perform the binding, or you can pass an optional model in the options as shown in the example above.

When binding to a view with a model, Backbone's validate method on the model is overridden to perform the validation. In addition, the model's isValid method is also overridden to provide some extra functionality.

Binding multiple views to same model

It is possible to bind several views to the same model. This is specially useful in UI structures where forms are made with components that share models.

When the model is validated all associated views with attributes from that model will validate its related elements.

It is also possible to unbind each view separately without affecting other bindings.

Binding to view with a collection

For this to work, your view must have an instance property named collection that holds your collection before you perform the binding, or you can pass an optional collection in the options as shown in the example above.

When binding to a view with a collection, all models in the collection are bound as described previously. When you are adding or removing models from your collection, they are bound/unbound accordingly.

Note that if you add/remove models with the silent flag, they will not be bound/unbound since there is no way of knowing the the collection was modified.

Unbinding

If you want to remove the validation binding, this is done with a call to Backbone.Validation.unbind(view). This removes the validation binding on the model, or all models if you view contains a collection, as well as removing all events hooked up on the collection.

Note that if you are binding to an optional model or collection, you must also specify this when unbinding: Backbone.Validation.unbind(view, {model: boundModel}).

Using model validation

The philosophy behind this way of using the plugin, is to give you an easy way to implement validation across all your models without the need to bind to a view. Of course, if you use this option the callbacks to update the view is not executed, since there is no way of knowing what view a model belongs to.

Validation mix-in

To add validation to your models, mix in the validation on the Model's prototype.

_.extend(Backbone.Model.prototype, Backbone.Validation.mixin);

Using server validation

If you are using node.js on your server, you can also reuse your models and validation on the server. For this to work you must share your models between the server and the client.

var backbone = require('backbone'),
    _ = require('underscore'),
    validation = require('backbone-validation');

_.extend(backbone.Model.prototype, validation.mixin);

Methods

validate

This is called by Backbone when it needs to perform validation. You can also call it manually without any parameters to validate the entire model.

isValid

Check to see if an attribute, an array of attributes or the entire model is valid.

isValid returns undefined when no validation has occurred and the model has validation (except with Backbone v0.9.9 where validation is called from the constructor), otherwise, true or false.

If you don't pass an argument, the properties defined by the attributes bind option will be validated. If no attributes option is used there will be no validation.

var isValid = model.isValid();

If you pass true as an argument, this will force a validation before the result is returned:

var isValid = model.isValid(true);

If you pass the name of an attribute or an array of names, you can check whether or not the attributes are valid:

// Check if name is valid
var isValid = model.isValid('name');

// Check if name and age are valid
var isValid = model.isValid(['name', 'age']);

preValidate

Sometimes it can be useful to check (for instance on each key press) if the input is valid - without changing the model - to perform some sort of live validation. You can execute the set of validators for an attribute, or a hash of attributes, by calling the preValidate method and pass it the name of the attribute and the value to validate, or a hash of attributes.

If the value is not valid, the error message is returned (truthy), otherwise it returns a falsy value.

// Validate one attribute
// The `errorsMessage` returned is a string
var errorMessage = model.preValidate('attributeName', 'Value');

// Validate a hash of attributes
// The errors object returned is a key/value pair of attribute name/error, e.g
// {
//   name: 'Name is required',
//   email: 'Email must be a valid email'
// }
var errors = model.preValidate({name: 'value', email: '[email protected]'});

Configuration

Callbacks

The Backbone.Validation.callbacks contains two methods: valid and invalid. These are called after validation of an attribute is performed when using form validation.

The default implementation of invalid tries to look up an element within the view with an name attribute equal to the name of the attribute that is validated. If it finds one, an invalid class is added to the element as well as a data-error attribute with the error message. The valid method removes these if they exists.

The implementation is a bit naïve, so I recommend that you override it with your own implementation

globally:

_.extend(Backbone.Validation.callbacks, {
  valid: function(view, attr, selector) {
    // do something
  },
  invalid: function(view, attr, error, selector) {
    // do something
  }
});

or, per view when binding:

var SomeView = Backbone.View.extend({
  render: function(){
    Backbone.Validation.bind(this, {
      valid: function(view, attr) {
        // do something
      },
      invalid: function(view, attr, error) {
        // do something
      }
    });
  }
});

Selector

Default: name

This configures what selector that will be used to look up a form element in the view. By default it uses name, but if you need to look up elements by class name or id instead, there are two ways to configure this.

You can configure it globally by calling:

Backbone.Validation.configure({
  selector: 'class'
});

Or, you can configure it per view when binding:

Backbone.Validation.bind(this.view, {
  selector: 'class'
});

If you have set the global selector to class, you can of course set the selector to name or id on specific views.

Force update

Default: false

Sometimes it can be useful to update the model with invalid values. Especially when using automatic modelbinding.

You can turn this on globally by calling:

Backbone.Validation.configure({
  forceUpdate: true
});

Or, you can turn it on per view when binding:

Backbone.Validation.bind(this.view, {
  forceUpdate: true
});

Or, you can turn it on for one set operation only (Backbone.VERSION >= 0.9.1 only):

model.set({attr: 'invalidValue'}, {
  forceUpdate: true
});

Note that when switching this on, Backbone's error event is no longer triggered.

Label formatter

Default: sentenceCase

Label formatters determines how an attribute name is transformed before it is displayed in an error message.

There are three options available:

  • 'none': Just returns the attribute name without any formatting
  • 'sentenceCase': Converts attributeName or attribute_name to Attribute name
  • 'label': Looks for a label configured on the model and returns it. If none found, sentenceCase is applied.
var Model = Backbone.Model.extend({
  validation: {
    someAttribute: {
      required: true
    }
  },

  labels: {
    someAttribute: 'Custom label'
  }
});

To configure which one to use, set the labelFormatter options in configure:

Backbone.Validation.configure({
  labelFormatter: 'label'
});

Attributes

The attributes option passed in Backbone.Validation.bind determines what model attributes must be validated. It can be an array, a function returning an array or an string that points to an registered attribute loader. By default, the 'inputNames' attribute loader is provided. It returns the name attribute of input elements in the view.

Per view when binding:

var SomeView = Backbone.View.extend({
  render: function(){
    Backbone.Validation.bind(this, {
        attributes: function(view) {
          return ['name', 'age']; // only name and age will be validated
        }
      }
    });
  }
});

Set default globally:

Backbone.Validation.configure({
  attributes: 'inputNames' // returns the name attributes of bound view input elements
});

Register an attribute loader:

_.extend(Backbone.Validation.attributeLoaders, {
  myLoader: function(view) {
    // return an array with the attributes to be validated
  }
});

Events

After validation is performed, the model will trigger some events with the result of the validation.

Note that the events reflects the state of the model, not only the current operation. So, if for some reason your model is in an invalid state and you set a value that is valid, validated:invalid will still be triggered, not validated:valid.

The errors object passed with the invalid events is a key/value pair of attribute name/error.

{
  name: 'Name is required',
  email: 'Email must be a valid email'
}

validated

The validated event is triggered after validation is performed, either it was successful or not. isValid is true or false depending on the result of the validation.

model.bind('validated', function(isValid, model, errors) {
  // do something
});

validated:valid

The validated:valid event is triggered after a successful validation is performed.

model.bind('validated:valid', function(model) {
  // do something
});

validated:invalid

The validated:invalid event is triggered after an unsuccessful validation is performed.

model.bind('validated:invalid', function(model, errors) {
  // do something
});

Built-in validators

method validator

Lets you implement a custom function used for validation.

var SomeModel = Backbone.Model.extend({
  validation: {
    name: function(value, attr, computedState) {
      if(value !== 'something') {
        return 'Name is invalid';
      }
    }
  }
});

var SomeModel = Backbone.Model.extend({
  validation: {
    name: {
      fn: function(value, attr, computedState) {
        if(value !== 'something') {
          return 'Name is invalid';
        }
      }
    }
  }
});

named method validator

Lets you implement a custom function used for validation.

var SomeModel = Backbone.Model.extend({
  validation: {
    name: 'validateName'
  },
  validateName: function(value, attr, computedState) {
    if(value !== 'something') {
      return 'Name is invalid';
    }
  }
});

var SomeModel = Backbone.Model.extend({
  validation: {
    name: {
      fn: 'validateName'
    }
  },
  validateName: function(value, attr, computedState) {
    if(value !== 'something') {
      return 'Name is invalid';
    }
  }
});

required

Validates if the attribute is required or not. This can be specified as either a boolean value or a function that returns a boolean value.

var SomeModel = Backbone.Model.extend({
  validation: {
    name: {
      required: true | false
    }
  }
});

var SomeModel = Backbone.Model.extend({
  validation: {
    name: {
      required: function(value, attr, computedState) {
        return true | false;
      }
    }
  }
});

acceptance

Validates that something has to be accepted, e.g. terms of use. true or 'true' are valid.

var SomeModel = Backbone.Model.extend({
  validation: {
    termsOfUse: {
      acceptance: true
    }
  }
});

min

Validates that the value has to be a number and equal to or greater than the min value specified.

var SomeModel = Backbone.Model.extend({
  validation: {
    age: {
      min: 1
    }
  }
});

max

Validates that the value has to be a number and equal to or less than the max value specified.

var SomeModel = Backbone.Model.extend({
  validation: {
      age: {
      max: 100
    }
  }
});

range

Validates that the value has to be a number and equal to or between the two numbers specified.

var SomeModel = Backbone.Model.extend({
  validation: {
    age: {
      range: [1, 10]
    }
  }
});

length

Validates that the value has to be a string with length equal to the length value specified.

var SomeModel = Backbone.Model.extend({
  validation: {
    postalCode: {
      length: 4
    }
  }
});

minLength

Validates that the value has to be a string with length equal to or greater than the min length value specified.

var SomeModel = Backbone.Model.extend({
  validation: {
    password: {
      minLength: 8
    }
  }
});

maxLength

Validates that the value has to be a string with length equal to or less than the max length value specified.

var SomeModel = Backbone.Model.extend({
  validation: {
    password: {
      maxLength: 100
    }
  }
});

rangeLength

Validates that the value has to be a string and equal to or between the two numbers specified.

var SomeModel = Backbone.Model.extend({
  validation: {
    password: {
      rangeLength: [6, 100]
    }
  }
});

oneOf

Validates that the value has to be equal to one of the elements in the specified array. Case sensitive matching.

var SomeModel = Backbone.Model.extend({
  validation: {
    country: {
      oneOf: ['Norway', 'Sweeden']
    }
  }
});

equalTo

Validates that the value has to be equal to the value of the attribute with the name specified.

var SomeModel = Backbone.Model.extend({
  validation: {
    password: {
      required: true
    },
    passwordRepeat: {
      equalTo: 'password'
    }
  }
});

pattern

Validates that the value has to match the pattern specified. Can be a regular expression or the name of one of the built in patterns.

var SomeModel = Backbone.Model.extend({
  validation: {
    email: {
      pattern: 'email'
    }
  }
});

The built-in patterns are:

  • number - Matches any number (e.g. -100.000,00)
  • email - Matches a valid email address (e.g. [email protected])
  • url - Matches any valid url (e.g. http://www.example.com)
  • digits - Matches any digit(s) (i.e. 0-9)

Specify any regular expression you like:

var SomeModel = Backbone.Model.extend({
  validation: {
    email: {
      pattern: /^sample/
    }
  }
});

Extending Backbone.Validation

Adding custom validators

If you have custom validation logic that are used several places in your code, you can extend the validators with your own. And if you don't like the default implementation of one of the built-ins, you can override it.

_.extend(Backbone.Validation.validators, {
  myValidator: function(value, attr, customValue, model) {
    if(value !== customValue){
      return 'error';
    }
  },
  required: function(value, attr, customValue, model) {
    if(!value){
      return 'My version of the required validator';
    }
  },
});

var Model = Backbone.Model.extend({
  validation: {
    age: {
      myValidator: 1 // uses your custom validator
    }
  }
});

The validator should return an error message when the value is invalid, and nothing (undefined) if the value is valid. If the validator returns false, this will result in that all other validators specified for the attribute is bypassed, and the attribute is considered valid.

Adding custom patterns

If you have custom patterns that are used several places in your code, you can extend the patterns with your own. And if you don't like the default implementation of one of the built-ins, you can override it.

Remember to also provide a default error message for it.

_.extend(Backbone.Validation.patterns, {
  myPattern: /my-pattern/,
  email: /my-much-better-email-regex/
});

_.extend(Backbone.Validation.messages, {
  myPattern: 'This is an error message'
});

var Model = Backbone.Model.extend({
  validation: {
    name: {
      pattern: 'myPattern'
    }
  }
});

Overriding the default error messages

If you don't like the default error messages you can easilly customize them by override the default ones globally:

_.extend(Backbone.Validation.messages, {
  required: 'This field is required',
  min: '{0} should be at least {1} characters'
});

The message can contain placeholders for arguments that will be replaced:

  • {0} will be replaced with the formatted name of the attribute being validated
  • {1} will be replaced with the allowed value configured in the validation (or the first one in a range validator)
  • {2} will be replaced with the second value in a range validator

Examples

  • Example 1: Uses jQuery.serializeObject to serialize the form and set all data on submit
  • Example 2: Uses StickIt to perform binding between the model and the view

If you have other cool examples, feel free to fork the fiddle, add a link here, and send me a pull request.

FAQ

What gets validated when?

If you are using Backbone v0.9.1 or later, all attributes in a model will be validated. However, if for instance name never has been set (either explicitly or with a default value) that attribute will not be validated before it gets set.

This is very useful when validating forms as they are populated, since you don't want to alert the user about errors in input not yet entered.

If you need to validate entire model (both attributes that has been set or not) you can call validate() or isValid(true) on the model.

Can I call one of the built in validators from a method validator?

Yes you can!

var Model = Backbone.Model.extend({
  validation: {
    name: function(val, attr, computed) {
      return Backbone.Validation.validators.length(val, attr, 4, this);
    }
  }
});

Can I call one of the built in validators from a custom validator?

Yes you can!

_.extend(Backbone.Validation.validators, {
  custom: function(value, attr, customValue, model) {
    return this.length(value, attr, 4, model) || this.custom2(value, attr, customValue, model);
  },
  custom2: function(value, attr, customValue, model) {
    if (value !== customValue) {
      return 'error';
    }
  }
});

How can I allow empty values but still validate if the user enters something?

By default, if you configure a validator for an attribute, it is considered required. However, if you want to allow empty values and still validate when something is entered, add required: false in addition to other validators.

validation: {
	value: {
		min: 1,
    required: false
  }
}

Do you support conditional validation?

Yes, well, sort of. You can have conditional validation by specifying the required validator as a function.

validation: {
  attribute: {
    required: function(val, attr, computed) {
      return computed.someOtherAttribute === 'foo';
    },
    length: 10
  }
}

In the example above, attribute is required and must have 10 characters only if someOtherAttribute has the value of foo. However, when attribute has any value it must be 10 characters, regardless of the value of someOtherAttribute.

Is there an elegant way to display the error message that is put into the data-error attribute?

The default implementation of the callbacks are a bit naïve, since it is very difficult to make a general implementation that suits everybody.

My recommendation is to override the callbacks and implement your own strategy for displaying the error messages.

Please refer to this section for more details.

How can I use it with Twitter Bootstrap?

driehle put together a gist in Coffee Script that helps rendering the error messages for Twitter Bootstrap:

https://gist.github.com/2909552

Basic behaviour:

  • The control-group gets an error class so that inputs get the red border
  • By default error messages get rendered as <p class="help-block"> (which has red text because of the error class)
  • You may use <input .... data-error-style="inline"> in your form to force rendering of a <span class="help-inline">

Release notes

v0.11.5 commits

  • Check for no associatedViews in unbindModel().

v0.11.4 commits

  • Support arrays in the attributes.

v0.11.3 commits

  • Upgrading version in source file. Fixes #274.

v0.11.2 commits

  • Triggers 'invalid' event when calling isValid and call valid/invalid callbacks when passing array or name to isValid.

v0.11.1 commits

  • Support intermediate nested levels

v0.11.0 commits

  • Support for binding multiple views to same model

v0.10.1 commits

  • Removed duplicated calls of flatten in validate method

v0.10.0 commits

  • attributes bind option allows to configure the attributes that will be validated

v0.9.2 commits

  • Fixed flatten() method causing Maximum call stack size exceeded errors. Fixes #260 #180 #210 #224 #233

v0.9.1 commits

  • Upgraded buster.js to v0.7.8
  • Updated contribute section in readme
  • Update README.md typo: i => is. Fixes #183
  • Fixed model unbind when model is also part of a collection of which other models have binding. Fixes #182

v0.9.0 commits

  • Fixed undefined format function when calling one of the built in validators form within a method validator. Fixes #98 and #111
  • BREAKING: Added ability to set error message per pattern. This means that if you have custom patterns, or have changed the message for one of the built in patterns, you need to add/change a default message for it. Fixes #174
  • BREAKING: length, maxLength, minLength and rangeLength validators no longer secretly trims the string. Fixes #134
  • Added new examples

v0.8.2 commits

  • preValidate now accepts a hash of attributes in addition to a key/value
  • msg attribute can be defined as both a function or a string
  • validation attribute can be defined as both a function or a hash
  • You can pass an optional model/collectionto bind to use instead of view.model/view.collection

v0.8.1 commits

  • No longer flattens arrays
  • Added required validator test for empty and non-empty arrays
  • Replaces all the underscores in sentenceCase formatter

v0.8.0 commits

  • All tests pass Backbone v1.0
  • Fixes recursive loop if model attributes contain nested models. Fixes #97 (Thanks to Adam George)
  • Handling id selectors better. Fixes #127 (Thanks to BigBlueHat)

v0.7.1 commits

  • Fixed Sizzle error: "unrecognized expression" (Thanks to Vladimir Tsvang)
  • Only binds to a collection when a model is not present on the view. Fixes #89
  • Tested with Backbone v0.9.9

v0.7.0 commits

v0.6.4 commits

  • format(...) and formatLabel(...) are made available for custom validators on this (Thanks to rafanoronha)

v0.6.3 commits

  • Labelformatter set to 'label' no longer crashes when no labels attribute is present on the model
  • Does not invoke callbacks for attributes that are not validated
  • Valid callbacks are always called before invalid callbacks (Thanks to Justin Etheredge)
  • Fixed typo in the readme

v0.6.2

v0.6.1

  • AMD and node.js support in a seperate download
  • Available on npm
  • Throws error if the view has no model or collection when executing the binding

v0.6.0

  • BREAKING: Nested validation is no longer supported as it came with too many issues with no obvious solution. Since it added more confusion than solving real problems, it is out until I can figure a better way of handling it.
  • BREAKING: The array with attribute names passed to the validated/error events is replaced with an object with attribute name and error message {name: "Name is required"}
  • Verified that all tests passes Backbone v0.9.2
  • Fixed misspelling in collectionAdd function (Fixes #28, thanks to morgoth)
  • Ensure model with custom toJSON() validates correctly (Fixes #31, thanks to jasonzhao6)
  • Wrong spelling of 'greater' as I'm sure we are not validating cheese (Fixes #35, thanks to JProgrammer)
  • Fixed error when using mixin and setting values on models without validation (Fixes #36)
  • Added preValidate(attr, value) method on validated models that can be used to preview if a value is valid or not
  • User friendly names for attributes in validation messages (Thanks to josjevv)
  • Required validator gets the same paramenters as method validator when specified as a function
  • Lots of code clean up and restructuring
  • Improved documentation

v0.5.2

  • Fixed equalTo validator when setting both values at the same time (Fixes #27)
  • Fixed removing invalid class in view when validating dependent attributes, and changing one makes the other valid

v0.5.1

  • error argument passed to the error event raised by Backbone is always an array
  • Can pass the name of an attribute or an array of names to isValid to verify if the attribute(s) are valid

v0.5.0

  • Support for Backbone v0.9.1
  • Support for object/nested validation (Fixed #20, thanks to AndyUK)
  • Support for binding to a view with a collection of models
  • Support for mixing in validation on Backbone.Model.prototype
  • Context (this) in custom validators is the Backbone.Validation.validators object
  • Calling unbind on a view without model no longer throws (Fixes #17)
  • Method validators get a computed model state (i.e. the state of the model if the current set operation succeeds) as the third argument (Fixes #22)
  • forceUpdate can be specified when settings attributes (Backbone.VERSION >= 0.9.1 only)

v0.4.0

  • isValid returns undefined when no validatation has occured and the model has validation
  • Passing true to isValid forces an validation
  • When specifying multiple validators for one attribute, all can have it's own error message (thanks to GarethElms)
  • method validator and named method validator can be combined with other built-in validators
  • acceptance validator accepts 'true' as valid (Fixes issue #12)
  • Can configure per view or globally to force update the model with invalid values. This can be very useful when using automatic modelbinding and late validation (e.g. when submitting the form)
  • email pattern is case insensitive
  • Breaking changes (unfortunate, but necessary):
    • setDefaultSelector is removed, and you need to call configure({selector: 'class'}) instead

v0.3.1

  • Fixed issue with validated events being triggered before model was updated
  • Added model and an array of invalid attribute names as arguments to the events

v0.3.0

  • Triggers events when validation is performed (thanks to GarethElms):
    • 'validated' with true or false as argument
    • 'validated:valid' when model is valid
    • 'validated:invalid' when model is invalid
  • Named method validator get the name of the attribute being validate as the second argument (thanks to goreckm)
  • error argument passed to the error event raised by Backbone contains an array of errors when validating multiple attributed in one go, otherwise a string
  • Breaking changes (unfortunate, but necessary):
    • isValid attribute (model.get('isValid')) is replaced with a method model.isValid()
    • Default selector is 'name' instead of 'id'

v0.2.0

  • New validators:
    • named method
    • length
    • acceptance (which is typically used when the user has to accept something (e.g. terms of use))
    • equalTo
    • range
    • rangeLength
    • oneOf
  • Added possibility to validate entire model by explicitly calling model.validate() without any parameters. (Note: Backbone.Validation.bind(..) must still be called)
  • required validator can be specified as a method returning either true or false
  • Can override the default error messages globally
  • Can override the id selector (#) used in the callbacks either globally or per view when binding
  • Improved email pattern for better matching
  • Added new pattern 'digits'
  • Possible breaking changes:
    • Removed the unused msg parameter when adding custom validators
    • Number pattern matches negative numbers (Fixes issue #4), decimals and numbers with 1000-separator (e.g. 123.000,45)
    • Context (this) in the method validators is now the model instead of the global object (Fixes issue #6)
    • All validators except required and acceptance invalidates null, undefined or empty value. However, required:false can be specified to allow null, undefined or empty value
  • Breaking changes (unfortunate, but necessary):
    • Required validator no longer invalidates false boolean, use the new acceptance validator instead

v0.1.3

  • Fixed issue where min and max validators treated strings with leading digits as numbers
  • Fixed issue with undefined Backbone reference when running Backbone in no conflict mode
  • Fixed issue with numeric string with more than one number not being recognized as a number

v0.1.2

  • Initial release

Contribute

In lieu of a formal styleguide, use two spaces for tabs and take care to maintain the existing coding style.

For a pull request to be accepted it must contain:

  • Only one change per request
  • Unit test(s)

Make sure that all tests passes before submitting your pull request.

npm install -g grunt-cli
npm install
grunt

Inspiration

Backbone.Validation is inspired by Backbone.ModelBinding, and another implementation with a slightly different approach than mine at Backbone.Validations.

License

http://thedersen.mit-license.org/

backbone.validation's People

Contributors

akshaddhoke avatar andyuk avatar asgeo1 avatar bigbluehat avatar blikblum avatar chiefgui avatar fg avatar garethelms avatar goreckm avatar igchuk avatar jasonzhao6 avatar jetheredge avatar jprogrammer avatar kinergy avatar marcingajda avatar millerren avatar morgoth avatar nuragic avatar patrickleet avatar pivotal-chorus avatar platinumazure avatar radagaisus avatar rafaelcasusoromate avatar rafanoronha avatar simenb avatar thedersen avatar tonofprince avatar vladtsf avatar werehamster avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

backbone.validation's Issues

custom invalid function not getting parameters

_.extend(Backbone.Model.prototype, Backbone.Validation.mixin);

var test = Backbone.Model.extend({
    validation: {
        value: {
            pattern: 'url'
         },
     },
     initialize: function(){
         this.bind('validated: invalid', this.invalid);
     },
     invalid: function(view, attr, error, selector){
         console.log(view, attr, error, selector);
    }
});

var t = new Test({value: 'hotdogs'});

When I run this, this is the result from the console:
>child [] undefined undefined

Where child is the model that was being validated, but all the other attributes are empty so I'm unaware as to what failed validation.

I'm trying to make it so if there's an invalid setting and there's a default set for that setting, it'll use the default to override the invalid value trying to be set.

Additionally, I must bind to validate:invalid in the model's initialization function, if I don't it will (nor the method I'm overwriting) get called at all.

Non-view model level validation is super important to us.

Check if a specific attribute is valid

Is there any way to check if a specific attribute is valid? I couldn't see any method for this.

The use case:
I have some attribute which value depends on two other attributes (the value is retrieved from an ajax call that is passed the value of the two other attributes).
The value is updated "on change".
Obviously, I don't want to make this call and set the value if the "two other attributes" are not valid.
I would preferably not repeat the validation logic into "on change" event.

Basically I would like to do:

if ( ! this.model.isValid("attr1")  && !this.model.isValid("attr2") ) { 
   return;
}
... ajaxstuff

Thanks

Provide more information to 'validated' event subscribers

I'm impressed with your validation plugin and how active you've been in updating and improving it. I like how you've given the flexibility to use the View specific functionality or just the model validation itself.

In my case I'm using just the model validation functionality and subscribing to the validated event that's triggered in the validate method defined within the mixin. This works well although it would be nice if more information was passed with the event. Currently only the result.invalidAttrs are provided. This makes it difficult to determine which rule failed in cases where a given attribute has multiple rules defined on it (Ex: FirstName has a minLength and maxLength rule) - and therefor impossible to get the correct error message.

There's probably a couple of ways to solve this. This simplest might be to pass the entire result object with the triggered event instead of just the result.invalidAttrs. I could then match up the error message to the invalid attribute. This would be a breaking change though - so I'm not sure how acceptable that is.

Example:

model.trigger('validated', model._isValid, model, result); 
model.trigger('validated:' + (model._isValid ? 'valid' : 'invalid'), model, result); 

Long term passing that result object could open the door to tracking multiple failed rules/messages per attribute and then be available to the event subscribers - but I didn't want to go down that road quite yet. That's probably a bigger question and change.

Callbacks (valid/invalid) being fired for all attributes

Hi, thanks a lot for this plugin.

I am trying to display an error message for a given form input on the blur event.

My view is:

class CMT.Views.NewSession extends Backbone.View
    events: 
        "blur input": "validateFormInput"

    initialize: (options) ->
        @model = new CMT.Models.Credential      
        Backbone.Validation.bind @

    validateFormInput: (evt) ->     
        attributeName = evt.currentTarget.name
        @model.set attributeName, evt.currentTarget.value
        @model.isValid(attributeName)

I have a helper where I will create the markup I need:

CMT.Helpers.ValidationHelper = 
    valid: (view, attr, selector) ->
        console.log "valid"
        console.log arguments

    invalid: (view, attr, error, selector) ->
        console.log "invalid"
        console.log arguments

_.extend Backbone.Validation.callbacks, CMT.Helpers.ValidationHelper

The problem I am facing is that the invalid callback is called for all the invalid attributes but the doc says:

These are called after validation of an attribute is performed

I would have thought that it is only called once for the attribute I tried to validate using

@model.isValid(attributeName)

Also, is it the right way to use this plugin to display an error message as the user fills up the form? Thx!!

required validator does not work

The logic of the build in required validator is not correct which results in valid models although required is set to true.

Line 303 currently states

if (isRequired && !hasValue(value)) {

Reversing the return value of hasValue results in a condition that will never work if (true && false)

You have to explicit check for the return value to get the desired condition state:

if (isRequired && hasValue(value) == false) {

Unfortunately this leads to further errors i am unable to debug because of missing time.

Until this is fixed models with a required attribute are not validated correctly.

Fix type error when using Model prototype

When using the validator as a Model prototype you may run into a type error on a model that does not have validation: defined.

I fixed it by checking first for validation then for the attr, but not sure if that is the best way because I'm not familiar with the rest of the code.

Near line 30:
var getValidators = function(model, validation, attr) {

  •          if(_.isEmpty(validation)) return;   //Seems to fix it.
           var attrValidation = validation[attr] || {};   //This line will throw the error if validation is undefined.
    

Multiple error messages per attribute

Hi,

I've made a change so that multiple error messages can be used for each validation type per attribute. This is useful so I can have a different message when the user omits a required field, and a different message when the user enters an invalid value for a field.

Sorry but I'm not sure about submitting pull requests yet, here it is :

GarethElms@2bffd3c

can't use forceUpdate:true and model.validate() together?

Hi,

I was wondering why you have this bit of code in the validation:

            if (!opt.forceUpdate && result.errorMessages.length > 0) {
                return result;
            }

The way I see it, you can't manually call model.validate() and get anything back when forceUpdate:true. It will always be undefined.

Required selects are validating when they haven't been selected

We're using both Model binding and backbone.validation.

For all other fields, when changing an empty field it appears to trigger validation only for that element.. But we have a bunch of s with placeholders (value=""). These all instantly trigger validation failures even though they have not been edited. To make matters worse, when submitting the form - even the the selects that have a value are triggering the "required" validation. Do not work at all?

Multiple error messages

Great plugin BTW

One thing - would be great if each type of error could have its own message (similar to the way Jquery validation works).

E.g. if I have

validation: {
    heading: {
         required: true,
         maxLength: 20,
         msg: 'We need a heading'
    },  
    description: {  
        required: true,
        minLength: 1,
        maxLength: 50,
        msg: 'We need a description'
    },
    price : {
        required: true,
        pattern: 'number',
        msg: 'Please enter a price'
    }

},

With the validation errors

 _.extend(Backbone.Validation.callbacks, {
  valid: function(view, attr, selector) {   
    $('#' + attr + "_error").html("");
    $('#' + attr + "_error").hide();
    return true;
  },
  invalid: function(view, attr, error, selector) {
      console.log(error);

  }
});

If my 'heading is empty'

invalid produces 'We need a headingWe need a heading'

Ideally should stop on the first error

Question: How to work with "Selector" functionality ?

Hi,

nice plugin!

I want to know: What is the most elegant way to display validation messages
in the ui / next to the form-item?

I've seen there is a selector feature, which will change the class and add data-error="error message".
I want to know more about this.

So, how to handle this? Is it meant in combination with another plugin or mechanism?

Thanks

not triggering backbone "error" event

Is it by choice that the backbone error event is no longer fired?
When I save a model with a basic error like a "required" attribute missing, the view updates correctly,
but the ajax post is still be called.
ie. this.model.save(params)
Should I be using:
this.model.set(params)
model.bind('validated:valid', function(model) {
this.model.save()
}

events question

Hi, consider the following view code:

MyView = Backbone.Views.extend({
events: {
"validated": "validated",
"validated:valid": "valid",
"validated:invalid": "invalid"
}
initialize: function() { Backbone.Validation.bind(this); },
validated: function() { console.log('validated'); },
valid: function() { console.log('valid'); },
invalid: function() { console.log('invalid'); }
});

If I force validation on the model, the "validated" event fires and my handler is called, but the "valid" and "invalid" sub event handlers are not. If I explicitly bind to them on the model, then they do fire. I have to add this:

Backbone.Validation.bind(this, { valid: this.valid, invalid: this.invalid });

and then my handlers are called. Why is this? I'd prefer to specify it in the events object and assign a handler for all three.

Number regex

Validation of numbers does not handle negative values

How to go about "allow blank"

How would I go about allowing a blank value?
For example:

validation:
  value:
    min: 1

That is validating false if an empty value is given.
I want the ability to allow blank values; "only validate if value is given"

As far as I can see I have to create a custom validator for this, or am I missing something?

Does not work with HTML5 date input type

Given a custom validation function, the "value" param is always undefined if you use a input with type="date". Possibly other html5 types like email will have this issue. Have not confirmed.

when does it get validated?

According to the FAQ, it only validates attributes that has been set, this is not true according to what I see, it always validates the whole model every time I try only setting one of the attributes and im using backbone 0.9, am I doing something wrong?

The way to test is to simply set an attribute model.set() without {silent:true} on a bunch of attributes that has required:true

Validating related attribute

The original Backbone Model's validate method allows to validate attributes based on another:

  validate: function(attrs) {
    if (attrs.end < attrs.start) {
      return "can't end before it starts";
    }
  }

In the above example, the attributes [start] and [end] are validated together. The [start] can't be validated alone, it depends on the [end] value.

With backbone.validation this is not possible.

One solution that does NOT work is trying to do this:

  validation: {
    start: function {value, attr} {
      if (this.get('end') < value) {
        return "can't end before it starts";
      }
    },
    end: function {value, attr} {
      if (this.get('start') > value) {
        return "can't end before it starts";
      }
    }
  }

It doesn't work since the .get() method returns the value currently set on the model and not the new value from the "attrs" array.

Any ideas?

I can suggest adding an optional "model" attribute to the validation:

  validation: {
    name: {
      maxlength: 50
    },
    age: {
      min: 40
    },
    model: function (attrs) {
      // here we can examine the model's attributes: name, age, start, end and so on...
      if (attrs.end < attrs.start) {
        return "can't end before it starts";
      }
    }
  }

please give me working example

Hi!

I am new to backbone as well as backbone validations.

Though you have given good explanation, I miss something and can't make it work on my project.

Please give me a simple working example with all files.

model, view, backbone.js version, and backbone.validation.js.

Thanks in advance!

Rendering error messages for Twitter Bootstrap

Here is a gist that helps rendering the error messages for Twitter Bootstrap, you may add it to your docs if you like:

https://gist.github.com/2909552

Basic behaviour:

  • The control-group gets an error class so that inputs get the red border
  • By default error messages get rendered as <p class="help-block"> (which has red text because of the error class)
  • You may use <input .... data-error-style="inline"> in your form to force rendering of a <span class="help-inline">

Have fun with it ;)

No invalid attributes returned when a model is invalid

Hi,

I've had a couple issues when I don't know why my model isn't validating. The invalid attributes array returns empty, even though something is invalid. This is because the attribute wasn't set.

For example:

mymodel.set({});   // name is required, but it's missing!
mymodel.model.bind('validated', function(valid, model, attr){
        refute(valid);
        assert.equals([], attr);
    });

Yet, if I set the attribute, I will get the invalid attribute back.

mymodel.set({name: null});  // name is defined, but null.
mymodel.model.bind('validated', function(valid, model, attr){
        refute(valid);
        assert.equals(['name'], attr);
    });

Hope my code makes sense. Is there a good reason for why it is working the way it is?

-- Andy

Valid Callback Called for Invalid Items

This is an issue that manifests itself most obviously when dealing with a model binder, however it isn't necessary to use one in order to see the bug. Furthermore as I understand it this is a change is a result of something in backbone 0.9.1 and not directly an issue relating to this plugin.

The issue in essence is a combination of the fact that an invalid value is not pushed into the model (I would consider this correct behavior) and that validators are firing for attributes that have not changed since the last validation (possibly incorrect behavior). The result is the following set of steps:

  1. User inputs an invalid value into an attribute
  2. Invalid event handler fires correctly
  3. The model is NOT updated as the value was invalid
  4. User inputs a valid or invalid value into a different attribute
  5. Validation on the different attribute fires correctly
  6. Validation on the attr in step 1 fires correctly with the original value, causing the valid callback to the fired

In the event that you're updating the DOM to reflect the fact that there was an error such as in the default valid and invalid callbacks, your DOM elements for the attribute in step 1 will be incorrectly set to the values specified in the valid callback despite the fact that the field contains an invalid value. This causes the DOM elements to reflect an incorrect validity for the value in the input field associated with attr.

The following javascript was executed on a blank HTML page with the following libraries loaded, in order:

  1. jquery 1.7.2
  2. underscore 1.3.3
  3. backbone 0.9.2
  4. backbone.validation 0.5.2
_.extend(Backbone.Validation.callbacks, {
    valid: function(view, attr, selector) {
        console.log("Valid fired for: " + attr);
                // Update the form to reflect a valid state for attr
    },
    invalid: function(view, attr, error, selector) {
        console.log("Invalid fired for: " + attr);
                // Update the form to reflect an invalid state for attr
    }
});

var Person = Backbone.Model.extend({
    validation: {
        firstName: {
            required: true,
            msg: "First name is required."
        },
        lastName: {
            required: true,
            msg: "Last name is required."
        }
    }
});

var View = Backbone.View.extend({
    model: new Person,
    initialize: function() {
        Backbone.Validation.bind(this);
    },
    render: function() {
        console.log("Setting First Name to Cody (A valid value.)");
        this.model.set({firstName: "Cody"});

        console.log("Setting First Name to FAKE (A valid value.)");
        this.model.set({firstName: "FAKE"});

        console.log("Setting First Name to empty string (An invalid value.)");
        this.model.set({firstName: ""});

        console.log("Setting Last Name to Rioux (A valid value.)");
        this.model.set({lastName: "Rioux"});

        console.log("Setting First Name to null (An invalid value.)");
        this.model.set({firstName: null});

        console.log("Setting Last Name to undefined (An invalid value.)");
        this.model.set({lastName: undefined});
    }
});

var test = new View;
test.render();

This yields the following output:

Setting First Name to Cody (A valid value.)
Valid fired for: firstName

Setting First Name to FAKE (A valid value.)
Valid fired for: firstName
Valid fired for: firstName

Setting First Name to empty string (An invalid value.)
Invalid fired for: firstName

Setting Last Name to Rioux (A valid value.)
Valid fired for: firstName
Valid fired for: lastName
Valid fired for: firstName

Setting First Name to null (An invalid value.)
Invalid fired for: firstName
Valid fired for: lastName

Setting Last Name to undefined (An invalid value.)
Valid fired for: firstName // This causes first name's DOM elements to reflect a valid status, despite the fact that the user cleared the field.
Invalid fired for: lastName


I understand the issue is with the way backbone handles validation, but is there any way to modify this library to prevent such events from occurring? Or is this working as intended?

Model Validation When Views use a Collection vs. a Model

I often create a view with a collection vs. a model when I want to add a new model to the collection. Using the collection.create() method works well, easy, etc. I feel like it gets messy when you try to create a view w/a model then add it to the collection as you need to reference both.

var view = new View({
    collection: myCollection,
    id: 'my-view'
});

Later on when I want to create the model I just use this:

this.collection.create({
    attr1: value,
    attr2: value
});

The normal backbone validation methods would kickoff on the save but of course I want to use backbone.validation. My issue is that backbone.validation looks for the view's model and does not consider a view's collection. I apologize if I've missed something in the documentation (or don't understand something about backbone itself) but it didn't jump out at me. Thoughts?

Support for Collections within a bound Model

I want to validate a collection which is inside the model which is bound to my view. As far as I can tell, there is no way to bind the models in that collection. I tried to do it as a custom implementation from the bound model, but couldn't get the callbacks to work. Is there a way to do this within the scope of this plugin?

Thanks!

backbone.validation integration with brunch.io

How to intergrate http://thedersen.github.com/backbone.validation/ with brunch.io i tried putting backbone.validation.js in vendor folder and

View = require './view'
template = require './templates/home'
User = require 'models/user'

module.exports = class HomeView extends View
id: 'home-view'
template: template

initialize: ->

 Backbone.Validation.bind(this)

 @user = new User

 console.log @user

 @user.validate()

Gives error

Uncaught TypeError: Object # has no method 'validate'

i tried all the steps nothing worked any help would be great

brunch/brunch#266

When model is invalid, model.set('attr', 'value') will not stick even if the property is valid

TL;DR: if a model's initial state after creation is invalid, then you can't set other attributes on the model until the offending attribute is fixed. calls to this.model.set('attr', 'value') are ignored.

Here's the long version: consider a model like this:

ED.Models.Time = Backbone.Model.extend({
    defaults: {
      connections: []
    },
    validation: {
      time: { required: true, msg: "You must set a time value" },
      connections: function (val) {
        if (!val || val.length === 0) { return "You must connect this to something"; }
      }
    }
  });

So, initially, connections is an empty array, and that means it is invalid according to the validation rules. The other validation rules are for properties that are fed values through an html form. They are required, but since they do not have a default value, validation skips them until you try to set them.

When I go to fill out the form, I have change events bound to all the form fields, and I'll do something like this:

timeChanged: function () {
      this.model.set('time', this.$('.ed-widget-timepicker')[0].value);
      console.log(JSON.stringify(this.model.toJSON()));
    }

So, initially, the view's model is invalid b/c it does not contain anything in the connections array. When I go to set the time, and trigger the timeChanged function above, you'll see that I try to set the time property on the model, but it does not take...validation is executed upon set, and the value is not set in the model b/c the model is invalid.

If I then add something to the connections array, so that attribute is now valid, and then try to set the time attribute, it does set the attribute properly on the model.

This is unexpected. I would have assumed that I could still set the time property even if the connections is invalid.

Validating specific values without changing the object

I'd like to be able to check if a value can be set to an attribute without actually setting the attribute.

Example usage:
When a user fills a form, I want to check (on each key press) if the input is valid - without changing the model. The model should change when the input's change event happens (on blur).

To allow for this I added the following code to the mixin object:

validateValue: function(value, attr) {
  return validateAttr(this, this.validation, attr, value, this.toJSON());
}

and now I can call it like this:

myModel.validateValue('http://google.com', 'website');

Do you think such a method would be useful for more users of the backbone.validation lib?

Datepicker validation error msg not shown

i am using bootstrap css .
where my datepicker script is

Order Date
<div data-date-format="dd-mm-yyyy" data-date="" class="datepicker input-append date controls">
<input type="text" id="date" name="date" readonly="" value="" class="span2 required">
<span class="add-on"><i class="icon-th"></i></span>
but when it is validate the div.control-group added with class "error" but that error msg is not shown please give me some suggestion for this problem

equalTo weird behavior

I am using Backbone 0.9.1 and as you are aware, there is a change the way models validate. As stated in the What gets validated when? part of the README the data needs to exist in the model before it can get validated, how should I use equalTo then? Because as I serialize the form and call validate on it, I use this.model.set(raw_json_of_form) but password is not set yet at that time.

My temporary hack/fix is to change equalTo to:

    equalTo: function(value, attr, equalTo, child, model) {
        if(value !== model[equalTo]) {
            return format(messages.equalTo, attr, equalTo);
        }
    },

Best way to validate attributes within an object?

What's the best way to validate attributes within an object?

For example my object is:

{
id: 123,
image: {
   name: 'test'
   }
}

To validate that my image object has a name, I must use a function. Then I lose the built-in validators. Could we have nested validators?

Nice project by the way - it's been very useful on our project. :)

Andy

silent:true on model.set() in the bind() method

Hi,

Great work, I'm using this project in my app. I had to add silent:true to the model.set() call when you're setting isValid in the bind() method.

Without silent:true the model's change event fired twice which caused my code to try to add the model to the collection twice.

model.set({
isValid: isValid},
{silent:true});

You may want to add this to the code because it's probably not desirable to have isValid trigger the change event

See my fork here :

GarethElms@d2f03be

Can't bind to the ID

The theme_name validation works fine. The ID validation will not bind to the form element. If i change the name the method works fine (but then the name is wrong and I lose ModelBinding)

    validation:
        theme_name:
            fn: (value, attr, computedState)->
                unless _.include(window.THEMES, value)
                    'theme required'
        id:
            fn: (value, attr, computedState)->
                unless _.include(_.map(window.TOPICS, (m)-> return m.id), value)
                    'topic required'

Nested validation is no longer supported...

hi

We have been using backbone.validation for about a month in our project.
It seems very user-friendly plugin and we are very pleased with him, but our whole project is built on nested models.
so we can't upgrade to v0.6.0. we going to production in 3 weeks can you please update if the nested validation will come back In the near future, if not can you suggest some work around.

Thanks!

forceUpdate: true bug?

I don't know if it is a bug or if I'm doing something wrong.

I have an model with 4 attributes and validations:

class gh.Models.SomeModel extends Backbone.Model
  defaults:
    attr1: ""
    attr2: ""
    attr3: ""
    attr4: ""

  validation:
    attr1:
      pattern: 'number'
    attr2:
      pattern: 'number'
    attr3:
      pattern: 'number'
    attr4:
      pattern: 'number'

end

Then I'm binding validation in a view:

class gh.Views.SomeView extends Backbone.View
  render: =>
    # omitted
    Backbone.Validation.bind @, { forceUpdate: true }
end

The problem I'm having is that even though I used forceUpdate: true all attributes is being validated on change.

Shouldn't forceUpdate "suppress" validation on set for this view?

I want to validate the model manually on save.

validateAll issue

Hi. I seem to be having an issue with validators being called multiple times. From what I see from the code, validateObject is called and it loops over all the post-set attributes of the model and determines if any are incorrect. This makes sense to me, and returns expected results. Then, however, if that pass turns out to be valid, validateObject calls validateAll which loops over just the attributes that have validators.

    isValid = validateAll(model, validation, attrs, computed, view, options);
}

My issue arises in this call to validateAll if the compute values are all correct. It calls validateAttr, but using the model.get value of the attribute (which returns the old value).

So, it calls the validators on your new value, and then again on the OLD value if the new value is valid? I don't really understand this behavior or is it a bug and I'm driving myself nuts trying to wrap my head around how it should work?

isValid returns true when model is invalid

Hi,

When using backbone.validation in conjunction with Derick Bailey's backbone.modelbinding plugin I seem to be having a similar problem to the one described in issue #21. I've put together a jsFiddle example (http://jsfiddle.net/simax/bEqnZ/) to try and demonstrate the issue.

When I unset a model property, by removing the firstname or lastname in the example the isValid(true) call still returns true. This doesn't appear to be correct, can you help?

TIA,
Simon

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.