Async validations
This commit is contained in:
parent
9dcd976546
commit
fbf118695e
|
@ -11,6 +11,8 @@ Validatable.validatesInclusionOf = getConfigurator('inclusion');
|
|||
Validatable.validatesExclusionOf = getConfigurator('exclusion');
|
||||
Validatable.validatesFormatOf = getConfigurator('format');
|
||||
Validatable.validate = getConfigurator('custom');
|
||||
Validatable.validateAsync = getConfigurator('custom', {async: true});
|
||||
Validatable.validateUniquenessOf = getConfigurator('uniqueness');
|
||||
|
||||
// implementation of validators
|
||||
var validators = {
|
||||
|
@ -68,8 +70,8 @@ var validators = {
|
|||
err();
|
||||
}
|
||||
},
|
||||
custom: function (attr, conf, err) {
|
||||
conf.customValidator.call(this, err);
|
||||
custom: function (attr, conf, err, cb) {
|
||||
conf.customValidator.call(this, err, cb);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -80,8 +82,8 @@ function getConfigurator(name, opts) {
|
|||
};
|
||||
}
|
||||
|
||||
Validatable.prototype.isValid = function () {
|
||||
var valid = true, inst = this;
|
||||
Validatable.prototype.isValid = function (callback) {
|
||||
var valid = true, inst = this, wait = 0, async = false;
|
||||
|
||||
// exit with success when no errors
|
||||
if (!this.constructor._validations) {
|
||||
|
@ -97,12 +99,29 @@ Validatable.prototype.isValid = function () {
|
|||
|
||||
this.trigger('validation', function () {
|
||||
this.constructor._validations.forEach(function (v) {
|
||||
if (validationFailed(inst, v)) {
|
||||
if (v[2] && v[2].async) {
|
||||
valid = false;
|
||||
async = true;
|
||||
wait += 1;
|
||||
validationFailed(inst, v, done);
|
||||
} else {
|
||||
if (validationFailed(inst, v)) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var asyncFail = false;
|
||||
function done(fail) {
|
||||
asyncFail = asyncFail || fail;
|
||||
if (--wait === 0 && callback) {
|
||||
callback(!asyncFail);
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) cleanErrors(this);
|
||||
|
||||
return valid;
|
||||
};
|
||||
|
||||
|
@ -114,7 +133,7 @@ function cleanErrors(inst) {
|
|||
});
|
||||
}
|
||||
|
||||
function validationFailed(inst, v) {
|
||||
function validationFailed(inst, v, cb) {
|
||||
var attr = v[0];
|
||||
var conf = v[1];
|
||||
var opts = v[2] || {};
|
||||
|
@ -153,6 +172,11 @@ function validationFailed(inst, v) {
|
|||
inst.errors.add(attr, message);
|
||||
fail = true;
|
||||
});
|
||||
if (cb) {
|
||||
validatorArguments.push(function () {
|
||||
cb(fail);
|
||||
});
|
||||
}
|
||||
validator.apply(inst, validatorArguments);
|
||||
return fail;
|
||||
}
|
||||
|
|
|
@ -231,3 +231,23 @@ it 'should validate a field using a custom validator', (test) ->
|
|||
|
||||
test.done()
|
||||
|
||||
it 'should validate asynchronously', (test) ->
|
||||
|
||||
validator = (err, done) ->
|
||||
setTimeout =>
|
||||
err 'async' if @name == 'bad name'
|
||||
done()
|
||||
, 100
|
||||
|
||||
User.validateAsync 'name', validator, message: async: 'hello'
|
||||
|
||||
user = new User validAttributes
|
||||
test.ok not user.isValid(), 'not valid because async validation'
|
||||
user.isValid (valid) ->
|
||||
test.ok valid, 'valid name'
|
||||
|
||||
user.name = 'bad name'
|
||||
user.isValid (valid) ->
|
||||
test.ok not valid, 'not valid name'
|
||||
test.done()
|
||||
|
||||
|
|
Loading…
Reference in New Issue