Created
August 24, 2011 11:22
-
-
Save olivernn/1167825 to your computer and use it in GitHub Desktop.
js model validations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Bill = Model('bill', function () { | |
this.use(Model.validations) | |
this.validatesPresenceOf(['attribute1', 'attribute2']) | |
this.validatesPresenceOf('another_attribute', { | |
'condition': function () { | |
// some condition if you need it | |
return true | |
} | |
}) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Model.validations = function (klass) { | |
var rules = rules; | |
// http://dl.dropbox.com/u/35146/js/tests/isNumber.html | |
var isNumeric = function (n) { | |
return !isNaN(parseFloat(n)) && isFinite(n); | |
}; | |
var defaultOptions = { | |
"condition": function () { return true; } | |
}; | |
var validationMethods = { | |
validatesExclusionOf: function (attrName, attrValue, options) { | |
if (options.condition.call(this)) { | |
if (options['in'].indexOf(attrValue) !== -1) { | |
this.errors.add(attrName, options.message || "should not be one of " + options['in'].join(', ')) | |
}; | |
}; | |
}, | |
validatesInclusionOf: function (attrName, attrValue, options) { | |
if (options.condition.call(this)) { | |
if (options['in'].indexOf(attrValue) === -1) { | |
this.errors.add(attrName, options.message || "should be one of " + options['in'].join(', ')) | |
}; | |
}; | |
}, | |
validatesPresenceOf: function (attrName, attrValue, options) { | |
if (options.condition.call(this)) { | |
if ((attrValue !== undefined && attrValue.length == 0) || (attrValue === undefined)) { | |
this.errors.add(attrName, options.message || "should not be blank"); | |
}; | |
}; | |
}, | |
// numeric strings will pass validation by default, i.e. "1" | |
validatesNumericalityOf: function (attrName, attrValue, options) { | |
var self = this; | |
var addError = function () { self.errors.add(attrName, options.message || "should be numeric"); }; | |
if (options.condition.call(this)) { | |
if (options.allowNumericStrings) { | |
if (!isNumeric(attrValue)) { | |
addError(); | |
}; | |
} else if (typeof(attrValue) != "number" || isNaN(attrValue)) { | |
addError(); | |
}; | |
}; | |
}, | |
validatesLengthOf: function (attrName, attrValue, options) { | |
if (options.condition.call(this)) { | |
if (attrValue.length < options.min || attrValue.length > options.max) { | |
this.errors.add(attrName, options.message || "is too short or too long"); | |
}; | |
}; | |
}, | |
validatesFormatOf: function (attrName, attrValue, options) { | |
if (options.condition.call(this)) { | |
if (!options["with"].test(attrValue)) { | |
this.errors.add(attrName, options.message || "is the wrong format"); | |
}; | |
}; | |
}, | |
validatesUniquenessOf: function (attrName, attrValue, options) { | |
var instanceToValidat = this | |
if (options.condition.call(this)) { | |
if (this.constructor | |
.select(function () { | |
return this !== instanceToValidat; | |
}) | |
.select(function () { | |
return this.attr(attrName) == attrValue; | |
}) | |
.count() > 0) { | |
this.errors.add(attrName, options.message || "should be unique"); | |
}; | |
}; | |
}, | |
validateEach: function (attrName, attrValue, options) { | |
if (options.condition.call(this)) { | |
options.withFn.call(this, this, attrName, attrValue) | |
}; | |
} | |
}; | |
var validate = function () { | |
for (ruleName in klass.validations) { | |
for (attributeName in klass.validations[ruleName]) { | |
var options = klass.validations[ruleName][attributeName] | |
validationMethods[ruleName].call( | |
this, | |
attributeName, | |
this.attr(attributeName), | |
$.extend({}, defaultOptions, options) | |
) | |
} | |
} | |
} | |
klass.validations = {} | |
for (validationMethod in validationMethods) { | |
// better way to do this without a self executing function? | |
klass[validationMethod] = (function () { | |
var methodName = validationMethod | |
return function (attr, options) { | |
if (!klass.validations[methodName]) klass.validations[methodName] = {} | |
var attrs = wrapArray(attr) | |
for (var i=0; i < attrs.length; i++) { | |
klass.validations[methodName][attrs[i]] = options | |
}; | |
} | |
})() | |
} | |
var wrapArray = function (obj) { | |
if ($.isArray(obj)) { | |
return obj | |
} else if (typeof obj === "undefined" || obj === null) { | |
return [] | |
} else { | |
return [obj] | |
} | |
} | |
klass.prototype.validate = validate | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment