Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow pre-validating against itself or another set of attributes #212

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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: '[email protected]');
var errors = model.preValidate({ name: 'value', email: '[email protected]' });

// 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
Expand Down
14 changes: 10 additions & 4 deletions src/backbone-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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));
}
},

Expand Down
25 changes: 25 additions & 0 deletions tests/preValidate.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ buster.testCase("preValidate", {
},
authenticated: {
required: false
},
passwordConfirmation: {
equalsTo: 'password'
}
}
});
Expand Down Expand Up @@ -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'});
}
}
}
});