fantactuka / backbone-validator Goto Github PK
View Code? Open in Web Editor NEWBackbone model-view validator
Home Page: http://fantactuka.github.io/backbone-validator
License: MIT License
Backbone model-view validator
Home Page: http://fantactuka.github.io/backbone-validator
License: MIT License
Let's say I have a model with a property called email
. I'd like to make email both required and also check that it has a valid format. I also want to provide a custom error message for both of these validators. At the moment it seems that this is only possible via overriding the Backbone.Validator.createMessage
method as shown here: https://github.com/fantactuka/backbone-validator#error-messages-generator
However, this proves to be insufficient when I need to know the context of the model. For example - I might want to include the model's name in the error message. Something like: User email is required
. I can't do it with the error message generator because there is no way of knowing the context.
I like how Backbone.Validation currently handles this:
validation: {
email: [
{ required: true, msg: app.i18n.gettext('User email is required') },
{ pattern: 'email', msg: app.i18n.gettext('User email is invalid') },
],
}
However, there are other shortcomings in that library which means I can't really use it.
Any chance you could implement & support this kind of validator declarations?
i try to use webpack load backbone
and backbone-validator.js
,
but
Uncaught TypeError: this.model.validate is not a function
something wrong?
New to this plugin - have tried a couple of other backbone validation plugins and this is exactly what I am looking for, so thanks :)
At the moment, a field which contains only whitespace is considered to pass the required
test. Would you consider this to be a bug, or as expected?
I would like some way of validating against whitespace-only fields, if this doesn't come under the required
test then perhaps against a new format
.
Would it be possible to treat an array as a collection even if it actually wasn't a collection? I personally like to keep my model properties "clean" - they should be simple objects (strings, arrays, etc), not Backbone models/collections. But it would be great if I could still validate them - perhaps it's possible to cast them to proper models/collections while validating?
Something like this could probably work?
var Recipient = Backbone.Model.extend({
validation: {
name: { required: true },
email: { required: true, format: 'email' }
}
});
var Recipients = Backbone.Collection.extend({ model: Recipient });
var Email = Backbone.Model.extend({
validation: {
recipients: {
collection: Recipients
}
}
});
Taking it a step further, it shouldn't be too hard to allow nested model validation like this:
var User = Backbone.Model.extend({
validation: { name: { required: true } }
});
var Document = Backbone.Model.extend({
validation: { user: { required: true, model: User } }
});
Implementing these could allow validating event complex nested data structures. Nested models inside nested models, etc...
The implementation shouldn't bee too hard to figure out. I could give it a go. But what do you think of the idea?
I'm trying to conditionally validate an attribute based on the state of another attribute (validating an App store URL, so if it's an iOS app validate iTunes Store URL, if Android then Google Play Store URL). I noticed that the scope of the validation function is the validation hash, and somehow the arguments is a key/value pair of the fields being validated without any values in them... Is there any way I can get access to the current model instance from this function?
It could utilize same helper getAttrsToValidate
as other model's helpers.
How to override the message on a global scope for default validators?
When I use required: false with another validator, like so:
validation: ->
name:
required: false
minLength: 3
It will always fail with a minLength
validation error, even if the field is blank. I'm poking around to see if there's a simple way to make required: false
override all other validators when the field is empty... but you will hopefully get there first. : )
Thanks for your help!
Let's say I have a model with the following data:
{
name: "Organization",
address: {
street: "Open road",
city: "Utopia",
country: "Atlantis"
}
}
How can I validate address.city
without messing with the model's data structure like here http://jsfiddle.net/fantactuka/6zh5y/? To be clearer - I do not wish to flatten the actual model data - I want to keep it nested. Is it perhaps possible to flatten the data for validation only? Some kind of pre-processing of data for validation?
Library should not break default Backbone functionality. Built https://travis-ci.org/fantactuka/backbone-validator/builds/5050752 is broken since isValid
method does not pass Backbone's tests.
The new 0.3.0 version is not yet published to npm. Wth npm, you have to publish every release, because npm creates a copy of the release on it's own repository.
It's possible to automate this in your release task with grunt. Here's an example - it's commented out, but you get the idea.
If the chain() function that begins on line 56 is is terminated by a value() call on line 79, then this library is compatible with lodash 3.x as well as underscore. As the lodash chain function is now 'lazy', it requires a value(). It seems that in either case, a value() call is the right thing.
Run each message
string through _.template()
to generate better error messages without having to resort to writing a custom message function. The template would automatically be passed an object containing attributeName, attributeValue, validatorName, expectation
This way a generic message like Is too short
can easily become something like Username must be 3 to 10 character long
It makes sense to have a separate method, e.g. validateAsync
, or specific option, that will run async validation.
In the code formats can be
Validator.formats = {
digits: ...,
number: ...,
email: ...
};
but in README.md example:
format
- pattern matching.
email
numeric
email
url
Doc is wrong?
Hello,
first of all, nice plugin !
But, most of the time, validators (in Zend, Laravel, Yii for example) return an object (associative array) as error. In your plugin, it returns an array of strings.
I modify the code to return this object key/value (validatorName/errorMessage).
This is what it looks like:
validate: function(attrs, validations, context)
{
var errors = {};
_.each(attrs, function(attrValue, attrName)
{
var validation = validations[attrName];
if(validation)
{
var error = this._validateAll(validation, attrName, attrValue, context, attrs);
if(_.size(error))
{
errors[attrName] = error;
}
}
}, this);
return _.size(errors) ? errors : null;
},
_validateAll: function(validations, attrName, attrValue, context, allAttrs)
{
context = context || this;
return _.inject(_.flatten([validations || []]), function(errors, validation)
{
_.chain(validation).omit('message').each(function(attrExpectation, validatorName)
{
var validator = this._validators[validatorName];
if (!validator)
{
throw new Error('Missed validator: ' + validatorName);
}
var result = validator.fn.apply(context, [attrValue, attrExpectation, allAttrs]);
if(result !== true)
{
var error = validation.message || result || createErrorMessage(attrName, attrValue, attrExpectation, validatorName, context) || validator.message || 'Invalid';
if(_.isFunction(error))
{
error = error.apply(context, [attrName, attrValue, attrExpectation, validatorName]);
}
errors[validatorName] = error;
}
}, this);
return errors;
},
{}, this);
}
It's another way of seeing validation... You can take it or not ;-)
I was trying to do the following:
var Email = Backbone.Model.extend({
validation: {
recipients: {
required: true,
collection: true
}
}
});
var email = new Email();
email.validate(); // throws: Uncaught TypeError: Cannot read property 'models' of undefined
But instead of getting the email model validated, Validator throws an error: Uncaught TypeError: Cannot read property 'models' of undefined
. Would it not make sense to check if the property is not undefined/null and is actually a collection before proceeding?
All levels error messages should be allowed to be a function.
model.triggerValidated(null, { email: [], password: [] })
will trigger validated:invalid
even though no errors specified for attributes
Validators may be dependent on model's state, say if I want a field to be required only if another field is true.
Example: I have a user who is either a kid or a parent, if it's a parent, I need their last name, if it's a kid, I don't need a last name.
#user.coffee
class User
isParent: ->
@get 'role' == 'parent'
validation:
first_name:
required: true # Required for all users
format: 'name'
minLength: 2
maxLength: 40
last_name:
required: -> @isParent() # Required for parents only
format: 'name'
minLength: 2
maxLength: 40
What do you think?
First, I must say that this is the best Backbone validation plugin I've come across. It provides just the basic stuff that is needed, yet is flexible enough if I want to go crazy :)
Here's a question - would you consider switching to UMD so that this plugin could also be used as a CommonJS module (for example, on node.js)?
Which leads to another question - could you publish this module on NPM?
I could help contributing the UMD part as well as adjusting the package.json
to meet NPM requirements.
Is there a way to call a function that validates the model as a whole instead of individual attributes. This would allow more flexible validation of relationship among attributes instead of just their values.
This also allows working with inherited model classes that already have a validate
method defined. For example, if you're working with a mobile backend like Parse.com, whose technology is based on Backbone but instead of Backbone.Model
, you are required to use Parse.Object
. This class has a method Parse.Object.validate
that takes care of a few behind the scene data fields. I'm trying to figure out a way to call Parse.Object.validate
either before or after the normal flow of backbone-validator
I find the following to be quite helpful, as many of my models require validation of numbers (note, not strings that contain numbers, rather, actual numbers, where for example, a value must be no less than 0 and no more than 100).
I'm curious if this would be more widely useful, and if so, if a PR would be welcomed for it. Thanks. Great library!
// Add min and max number validators to Backbone Validator
function validNumber (value, expectation, valid) {
return _.isFinite(value) ? valid(value, expectation) : 'Value not a number';
}
Validator.add('min', function (value, expectation) {
return validNumber(value, expectation, function (value, expectation) {
return (value >= expectation) || 'Value below minimum';
});
});
Validator.add('max', function (value, expectation) {
return validNumber(value, expectation, function (value, expectation) {
return (value <= expectation) || 'Value above maximum';
});
});
I need validate a attr depends on other attr, so I thinks if we can pass attrs to fn validator would be nice.
Example:
var OrderItem = Backbone.Model.extend({
validation: function() {
return {
discount: {
fn: function(value, attrs) {
return value > (this.get('price') * attrs['quantity']) ? 'Discount can not greater than amount' : true;
}
}
}
}
});
Currently, when validating a model that has a nested collection, and the collection contains invalid data, the resulting error object is pretty crazy with nested arrays. Can we perhaps provide an option to return a flattened object with flattened paths, pretty much like Mongoose does?
Given a model:
var User = Backbone.Model.extend({
validation: {
books: { collection: true }
}
});
Instead of this:
{ books: [[0, { name: ["Name is required"] }], [1, { author: ["Author is required"] }]] }
it would return this:
{ 'books.0.name': 'Name is required', 'books.1.author': 'Author is required' }
Perhaps this could be controlled by an option passed to the validate() method? Something like: model.validate(null, { flatten: true });
.
More information: https://en.wikipedia.org/wiki/Email_address#Examples
It makes sense to have one top-level message function, that could be used as message generator, e.g. using i18n:
Backbone.Validator.createErrorMessage = function(attrName, attrValue, validatorExpectation, validatorName) {
return i18n.errors[attrName][validatorName];
};
And probably some kind of flag to indicate that user want to force default error messages to the generated (unless specific message for validator used). E.g.
Backbone.Validator.forceGlobalErrorMessageGeneratorToBeUsedInsteadOfDefaultMessages
Hi, will you be tagging a new release soon?
We really love this validator since it works correctly with all our wishes (Backbone-associations, Marionette, and Stickit) but we could really use your latest commits in a release
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.