Permalink
Browse files

Rules now meet issue #30 spec - all rules accept empty strings except…

… required
  • Loading branch information...
1 parent 835a47e commit 194135787a6f77e9f5e3d0f770351ea1f1a5b251 @ericmbarnard committed Apr 13, 2012
Showing with 124 additions and 16 deletions.
  1. +24 −12 Src/knockout.validation.js
  2. +100 −4 Tests/validation-tests.js
View
@@ -105,6 +105,17 @@
break;
}
return undefined;
+ },
+ isEmptyVal: function (val) {
+ if (val === undefined) {
+ return true;
+ }
+ if (val === null) {
+ return true;
+ }
+ if (val === "") {
+ return true;
+ }
}
};
} ());
@@ -399,42 +410,42 @@
ko.validation.rules['min'] = {
validator: function (val, min) {
- return !val || val >= min;
+ return utils.isEmptyVal(val) || val >= min;
},
message: 'Please enter a value greater than or equal to {0}.'
};
ko.validation.rules['max'] = {
validator: function (val, max) {
- return !val || val <= max;
+ return utils.isEmptyVal(val) || val <= max;
},
message: 'Please enter a value less than or equal to {0}.'
};
ko.validation.rules['minLength'] = {
validator: function (val, minLength) {
- return val && val.length >= minLength;
+ return utils.isEmptyVal(val) || val.length >= minLength;
},
message: 'Please enter at least {0} characters.'
};
ko.validation.rules['maxLength'] = {
validator: function (val, maxLength) {
- return !val || val.length <= maxLength;
+ return utils.isEmptyVal(val) || val.length <= maxLength;
},
message: 'Please enter no more than {0} characters.'
};
ko.validation.rules['pattern'] = {
validator: function (val, regex) {
- return !val || val.match(regex) != null;
+ return utils.isEmptyVal(val) || val.match(regex) != null;
},
message: 'Please check this value.'
};
ko.validation.rules['step'] = {
validator: function (val, step) {
- return val % step === 0;
+ return utils.isEmptyVal(val) || val % step === 0;
},
message: 'The value must increment by {0}'
};
@@ -443,7 +454,7 @@
validator: function (val, validate) {
//I think an empty email address is also a valid entry
//if one want's to enforce entry it should be done with 'required: true'
- return (!val) || (
+ return utils.isEmptyVal(val) || (
validate && /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(val)
);
},
@@ -452,35 +463,36 @@
ko.validation.rules['date'] = {
validator: function (value, validate) {
- return validate && !/Invalid|NaN/.test(new Date(value));
+ return utils.isEmptyVal(value) || (validate && !/Invalid|NaN/.test(new Date(value)));
},
message: 'Please enter a proper date'
};
ko.validation.rules['dateISO'] = {
validator: function (value, validate) {
- return validate && /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
+ return utils.isEmptyVal(value) || (validate && /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value));
},
message: 'Please enter a proper date'
};
ko.validation.rules['number'] = {
validator: function (value, validate) {
- return validate && /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
+ return utils.isEmptyVal(value) || (validate && /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value));
},
message: 'Please enter a number'
};
- ko.validation.rules['digits'] = {
+ ko.validation.rules['digit'] = {
validator: function (value, validate) {
- return validate && /^\d+$/.test(value);
+ return utils.isEmptyVal(value) || (validate && /^\d+$/.test(value));
},
message: 'Please enter a digit'
};
ko.validation.rules['phoneUS'] = {
validator: function (phoneNumber, validate) {
if (typeof (phoneNumber) !== 'string') { return false; }
+ if (utils.isEmptyVal(phoneNumber)) { return true; } // makes it optional, use 'required' rule if it should be required
phoneNumber = phoneNumber.replace(/\s+/g, "");
return validate && phoneNumber.length > 9 && phoneNumber.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
},
View
@@ -50,6 +50,13 @@ test('Empty spaces is not a valid value for required', function () {
module('Min Validation');
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ min: 2 });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('')
.extend({ min: 2 });
@@ -74,6 +81,14 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region Max Validation
module('Max Validation');
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ max: 2 });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('')
.extend({ max: 5 });
@@ -99,6 +114,15 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region Min Length Validation
module('MinLength Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ minLength: 2 });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+
+});
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('')
.extend({ minLength: 5 });
@@ -124,6 +148,14 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region Max Length Validation
module('MaxLength Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ maxLength: 2 });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('')
.extend({ maxLength: 10 });
@@ -149,6 +181,14 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region Pattern Validation
module('Pattern Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ pattern: 'test' });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('')
.extend({ pattern: 'some' });
@@ -174,6 +214,14 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region Step Validation
module('Step Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ step: 2 });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('')
.extend({ step: 3 });
@@ -199,6 +247,14 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region Email Validation
module('Email Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ email: true });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('').extend({ email: true });
@@ -222,6 +278,14 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region Date Validation
module('Date Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ date: 'test' });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('').extend({ date: true });
@@ -245,6 +309,14 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region DateISO Validation
module('DateISO Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ dateISO: 'test' });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('').extend({ dateISO: true });
@@ -268,6 +340,14 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region Number Validation
module('Number Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ number: true });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('').extend({ number: true });
@@ -291,8 +371,16 @@ test('Object is NOT Valid and isValid returns False', function () {
//#region Digit Validation
module('Digit Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ digit: true });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
test('Object is Valid and isValid returns True', function () {
- var testObj = ko.observable('').extend({ number: true });
+ var testObj = ko.observable('').extend({ digit: true });
testObj(2);
@@ -301,7 +389,7 @@ test('Object is Valid and isValid returns True', function () {
});
test('Object is NOT Valid and isValid returns False', function () {
- var testObj = ko.observable('').extend({ number: true });
+ var testObj = ko.observable('').extend({ digit: true });
testObj('stuff');
@@ -312,8 +400,16 @@ test('Object is NOT Valid and isValid returns False', function () {
//#endregion
//#region PhoneUS Validation
-
module('PhoneUS Validation');
+
+test('Object is Valid when no value is present - Preserves Optional Properties', function () {
+
+ var testObj = ko.observable().extend({ phoneUS: true });
+ testObj('');
+ ok(testObj.isValid(), 'testObj is Valid');
+});
+
+
test('Object is Valid and isValid returns True', function () {
var testObj = ko.observable('').extend({ phoneUS: true });
@@ -614,7 +710,7 @@ module('Grouping Tests');
test('Error Grouping works', function () {
var vm = {
firstName: ko.observable().extend({ required: true }),
- lastName: ko.observable().extend({ minLength: 2 })
+ lastName: ko.observable().extend({ required: 2 })
};
var errors = ko.validation.group(vm);

0 comments on commit 1941357

Please sign in to comment.