From 69e4efd42c545a6e5b98202d0d794ceb39ac7f7f Mon Sep 17 00:00:00 2001 From: Illimar Tambek Date: Thu, 27 Feb 2014 17:47:51 +0200 Subject: [PATCH] Allow pre-validating against itself or another set of attributes instead of the model's current attributes --- README.md | 10 +++++++++- src/backbone-validation.js | 14 ++++++++++---- tests/preValidate.js | 25 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b95cc96f..9eeb672a 100644 --- a/README.md +++ b/README.md @@ -253,6 +253,8 @@ var isValid = model.isValid(['name', 'age']); 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. +Optionally, it's possible to pass in a hash of attributes that will be used when comparing values, for example - in the `equalsTo` validator. This allows you to preValidate attributes against another set of attributes instead of your model's current attributes. + If the value is not valid, the error message is returned (truthy), otherwise it returns a falsy value. ```js @@ -266,7 +268,13 @@ var errorMessage = model.preValidate('attributeName', 'Value'); // name: 'Name is required', // email: 'Email must be a valid email' // } -var errors = model.preValidate({name: 'value', email: 'foo@example.com'); +var errors = model.preValidate({ name: 'value', email: 'foo@example.com' }); + +// Validate a hash of attributes against itself +// Pass in either `true` or an attribute hash as the 2nd parameter. +// Neither of the examples below will result in any errors. +var errors = model.preValidate({ password: 'value', passwordConfirmation: 'value' }, true); +var errors = model.preValidate({ password: 'value' }, { passwordConfirmation: 'value' }); ``` ## Configuration diff --git a/src/backbone-validation.js b/src/backbone-validation.js index 4e1da56a..a2794dc2 100644 --- a/src/backbone-validation.js +++ b/src/backbone-validation.js @@ -176,15 +176,21 @@ Backbone.Validation = (function(_){ return { // Check whether or not a value, or a hash of values - // passes validation without updating the model - preValidate: function(attr, value) { + // passes validation without updating the model. + // Optional 3rd param lets user pass in a hash of attributes + // to pass to validateAttr as the computed attributes + preValidate: function(attr, value, atts) { var self = this, result = {}, error; if(_.isObject(attr)){ + // If value is an object hash, use it as the atts object. + // If value is boolean = true, simply use attr object as the atts object. + atts = _.isObject(value) ? value : value === true ? attr : undefined; + _.each(attr, function(value, key) { - error = self.preValidate(key, value); + error = self.preValidate(key, value, atts); if(error){ result[key] = error; } @@ -193,7 +199,7 @@ Backbone.Validation = (function(_){ return _.isEmpty(result) ? undefined : result; } else { - return validateAttr(this, attr, value, _.extend({}, this.attributes)); + return validateAttr(this, attr, value, atts || _.extend({}, this.attributes)); } }, diff --git a/tests/preValidate.js b/tests/preValidate.js index 74009bb0..1aad0e3c 100644 --- a/tests/preValidate.js +++ b/tests/preValidate.js @@ -23,6 +23,9 @@ buster.testCase("preValidate", { }, authenticated: { required: false + }, + passwordConfirmation: { + equalsTo: 'password' } } }); @@ -64,6 +67,28 @@ buster.testCase("preValidate", { "returns nothing when value is valid": function() { refute(this.model.preValidate({name: 'name'})); } + }, + + "and pre-validating hash of attributes against itself (2nd param is `true`)": { + "returns error object when value is not valid": function() { + var result = this.model.preValidate({password: 'password', passwordConfirmation: 'passWORT'}, true); + assert(result.passwordConfirmation); + }, + + "returns nothing when value is valid": function() { + refute(this.model.preValidate({password: 'password', passwordConfirmation: 'password'}, true)); + } + }, + + "and pre-validating hash of attributes against another hash of attributes (2nd param is a hash)": { + "returns error object when value is not valid": function() { + var result = this.model.preValidate({passwordConfirmation: 'passWORT'}, {password: 'password'}); + assert(result.passwordConfirmation); + }, + + "returns nothing when value is valid": function() { + refute(this.model.preValidate({passwordConfirmation: 'password'}, {password: 'password'}); + } } } }); \ No newline at end of file