diff --git a/dist/knockout.validation.js b/dist/knockout.validation.js index 07b697b6..3b207fb1 100644 --- a/dist/knockout.validation.js +++ b/dist/knockout.validation.js @@ -58,6 +58,7 @@ var defaults = { live: false //react to changes to observableArrays if observable === true }, validate: { + setModifiedOnChange: true, // enables setting `isModified(true)` when observable changes // throttle: 10 } }; @@ -288,9 +289,7 @@ kv.configuration = configuration; forEach(array, function (observable) { // Do not collect validatedObservable errors if (utils.isValidatable(observable) && !observable.isValid()) { - // Use peek because we don't want a dependency for 'error' property because it - // changes before 'isValid' does. (Issue #99) - errors.push(observable.error.peek()); + errors.push(observable.error()); } }); return errors; @@ -1182,138 +1181,31 @@ ko.extenders['validation'] = function (observable, rules) { // allow single rule return observable; }; -//This is the extender that makes a Knockout Observable also 'Validatable' -//examples include: -// 1. var test = ko.observable('something').extend({validatable: true}); -// this will ensure that the Observable object is setup properly to respond to rules -// -// 2. test.extend({validatable: false}); -// this will remove the validation properties from the Observable object should you need to do that. -ko.extenders['validatable'] = function (observable, options) { - if (!kv.utils.isObject(options)) { - options = { enable: options }; - } - - if (!('enable' in options)) { - options.enable = true; - } - - if (options.enable && !kv.utils.isValidatable(observable)) { - var config = kv.configuration.validate || {}; - var validationOptions = { - throttleEvaluation : options.throttle || config.throttle - }; - - observable.error = ko.observable(null); // holds the error message, we only need one since we stop processing validators when one is invalid - - // observable.rules: - // ObservableArray of Rule Contexts, where a Rule Context is simply the name of a rule and the params to supply to it - // - // Rule Context = { rule: '', params: '', message: '' } - observable.rules = ko.observableArray(); //holds the rule Contexts to use as part of validation - - //in case async validation is occurring - observable.isValidating = ko.observable(false); - - //the true holder of whether the observable is valid or not - observable.__valid__ = ko.observable(true); - - observable.isModified = ko.observable(false); - - // a semi-protected observable - observable.isValid = ko.computed(observable.__valid__); - - //manually set error state - observable.setError = function (error) { - var previousError = observable.error.peek(); - var previousIsValid = observable.__valid__.peek(); - - observable.error(error); - observable.__valid__(false); - - if (previousError !== error && !previousIsValid) { - // if the observable was not valid before then isValid will not mutate, - // hence causing any grouping to not display the latest error. - observable.isValid.notifySubscribers(); - } - }; - - //manually clear error state - observable.clearError = function () { - observable.error(null); - observable.__valid__(true); - return observable; - }; - - //subscribe to changes in the observable - var h_change = observable.subscribe(function () { - observable.isModified(true); - }); - - // we use a computed here to ensure that anytime a dependency changes, the - // validation logic evaluates - var h_obsValidationTrigger = ko.computed(extend({ - read: function () { - var obs = observable(), - ruleContexts = observable.rules(); - - kv.validateObservable(observable); - - return true; - } - }, validationOptions)); - - extend(h_obsValidationTrigger, validationOptions); - - observable._disposeValidation = function () { - //first dispose of the subscriptions - observable.isValid.dispose(); - observable.rules.removeAll(); - h_change.dispose(); - h_obsValidationTrigger.dispose(); - - delete observable['rules']; - delete observable['error']; - delete observable['isValid']; - delete observable['isValidating']; - delete observable['__valid__']; - delete observable['isModified']; - delete observable['setError']; - delete observable['clearError']; - delete observable['_disposeValidation']; - }; - } else if (options.enable === false && observable._disposeValidation) { - observable._disposeValidation(); - } - return observable; -}; - function validateSync(observable, rule, ctx) { //Execute the validator and see if its valid if (!rule.validator(observable(), (ctx.params === undefined ? true : unwrap(ctx.params)))) { // default param is true, eg. required = true //not valid, so format the error message and stick it in the 'error' variable - observable.setError(kv.formatMessage( - ctx.message || rule.message, - unwrap(ctx.params), - observable)); - return false; - } else { - return true; + return kv.formatMessage( + ctx.message || rule.message, + unwrap(ctx.params), + observable + ); } + return null; } function validateAsync(observable, rule, ctx) { - observable.isValidating(true); + observable.__isValidatingAsync(true); - var callBack = function (valObj) { + var callback = function (valObj) { var isValid = false, msg = ''; - if (!observable.__valid__()) { + if (observable.__errorManual() || observable.__errorSync()) { // since we're returning early, make sure we turn this off - observable.isValidating(false); + observable.__isValidatingAsync(false); return; //if its already NOT valid, don't add to that } @@ -1328,58 +1220,201 @@ function validateAsync(observable, rule, ctx) { if (!isValid) { //not valid, so format the error message and stick it in the 'error' variable - observable.error(kv.formatMessage( - msg || ctx.message || rule.message, - unwrap(ctx.params), - observable)); - observable.__valid__(isValid); + observable.__errorAsync( + kv.formatMessage( + msg || ctx.message || rule.message, + unwrap(ctx.params), + observable + ) + ); } // tell it that we're done - observable.isValidating(false); + observable.__isValidatingAsync(false); }; kv.utils.async(function() { - //fire the validator and hand it the callback - rule.validator(observable(), ctx.params === undefined ? true : unwrap(ctx.params), callBack); + //fire the validator and hand it the callback + rule.validator( + observable(), + ctx.params === undefined ? true : unwrap(ctx.params), + callback + ); }); } -kv.validateObservable = function (observable) { - var i = 0, - rule, // the rule validator to execute - ctx, // the current Rule Context for the loop - ruleContexts = observable.rules(), //cache for iterator - len = ruleContexts.length; //cache for iterator +//This is the extender that makes a Knockout Observable also 'Validatable' +//examples include: +// 1. var test = ko.observable('something').extend({validatable: true}); +// this will ensure that the Observable object is setup properly to respond to rules +// +// 2. test.extend({validatable: false}); +// this will remove the validation properties from the Observable object should you need to do that. +ko.extenders['validatable'] = function (observable, options) { + if (!kv.utils.isObject(options)) { + options = { enable: options }; + } - for (; i < len; i++) { + options = extend(extend({ + enable: true, + }, kv.configuration.validate), options); - //get the Rule Context info to give to the core Rule - ctx = ruleContexts[i]; + if (options.enable && !kv.utils.isValidatable(observable)) { + var validationOptions = { + throttleEvaluation : options.throttle, + }; - // checks an 'onlyIf' condition - if (ctx.condition && !ctx.condition()) { - continue; - } + // holds an error set by setError (and cleared by clearError) + observable.__errorManual = ko.observable(null); - //get the core Rule to use for validation - rule = ctx.rule ? kv.rules[ctx.rule] : ctx; + // holds an error from synchronous validation rules + observable.__errorSync = ko.pureComputed(function () { + var i, + rule, // the rule validator to execute + ctx, // the current Rule Context for the loop + ruleContexts = observable.rules(), //cache for iterator + len = ruleContexts.length, //cache for iterator + error = null; - if (rule['async'] || ctx['async']) { - //run async validation - validateAsync(observable, rule, ctx); + for (i = 0; i < len; i++) { - } else { - //run normal sync validation - if (!validateSync(observable, rule, ctx)) { - return false; //break out of the loop + //get the Rule Context info to give to the core Rule + ctx = ruleContexts[i]; + + // checks an 'onlyIf' condition + if (ctx.condition && !ctx.condition()) { + continue; + } + + //get the core Rule to use for validation + rule = ctx.rule ? kv.rules[ctx.rule] : ctx; + + if (rule['async'] || ctx['async']) { + // skip async rules + continue; + + } else { + //run normal sync validation + error = validateSync(observable, rule, ctx); + if (error) { + return error; //break out of the loop + } + } } + + // all sync rules are satisfied, fire async validation + (function () { + for (i = 0; i < len; i++) { + + //get the Rule Context info to give to the core Rule + ctx = ruleContexts[i]; + + // checks an 'onlyIf' condition + if (ctx.condition && !ctx.condition()) { + continue; + } + + //get the core Rule to use for validation + rule = ctx.rule ? kv.rules[ctx.rule] : ctx; + + if (rule['async'] || ctx['async']) { + validateAsync(observable, rule, ctx); + + } else { + // skip sync rules + continue; + } + } + }()); + + return null; + }); + + extend(observable.__errorSync, validationOptions); + + // holds an error from asynchronous validation rules + observable.__errorAsync = ko.observable(null); + // is async validation currently running + observable.__isValidatingAsync = ko.observable(false); + + // holds the overall error message + observable.error = ko.pureComputed(function () { + return observable.__errorManual() || observable.__errorSync() || observable.__errorAsync() || null; + }); + + // readonly overall validity status + observable.isValid = ko.pureComputed(function () { + return !observable.error(); + }); + + // readonly "async validation is running" + observable.isValidating = ko.pureComputed(observable.__isValidatingAsync); + + // observable.rules: + // ObservableArray of Rule Contexts, where a Rule Context is simply the name of a rule and the params to supply to it + // + // Rule Context = { rule: '', params: '', message: '' } + observable.rules = ko.observableArray(); //holds the rule Contexts to use as part of validation + + // this could also be called `isMessageVisible` + observable.isModified = ko.observable(false); + + //manually set error state + observable.setError = function (error) { + observable.__errorManual(error); + return observable; + }; + + //manually clear error state + observable.clearError = function () { + observable.__errorManual(null); + return observable; + }; + + var h_change; + if (options.setModifiedOnChange) { + //subscribe to changes in the observable + h_change = observable.subscribe(function () { + observable.isModified(true); + }); } + + observable._disposeValidation = function () { + // first dispose of the subscriptions + observable.rules.removeAll(); + observable.clearError(); + observable.__errorSync.dispose(); + observable.error.dispose(); + observable.isValid.dispose(); + observable.isValidating.dispose(); + + if (h_change) { + h_change.dispose(); + } + + delete observable.__errorManual; + delete observable.__errorSync; + delete observable.__errorAsync; + delete observable.__isValidatingAsync; + delete observable.error; + delete observable.isValid; + delete observable.isValidating; + delete observable.rules; + delete observable.isModified; + delete observable.setError; + delete observable.clearError; + delete observable._disposeValidation; + }; + } else if (options.enable === false && observable._disposeValidation) { + observable._disposeValidation(); } - //finally if we got this far, make the observable valid again! - observable.clearError(); - return true; + return observable; }; + +kv.validateObservable = function (observable) { + return observable.isValid(); +}; + ; var _locales = {}; var _currentLocale; diff --git a/dist/knockout.validation.min.js b/dist/knockout.validation.min.js index 97eaad41..88f1a24a 100644 --- a/dist/knockout.validation.min.js +++ b/dist/knockout.validation.min.js @@ -7,5 +7,5 @@ =============================================================================== */ -!function(a){"function"==typeof require&&"object"==typeof exports&&"object"==typeof module?a(require("knockout"),exports):"function"==typeof define&&define.amd?define(["knockout","exports"],a):a(ko,ko.validation={})}(function(a,b){function c(a){var b="max"===a;return function(c,d){if(f.utils.isEmptyVal(c))return!0;var e,g;void 0===d.typeAttr?(g="text",e=d):(g=d.typeAttr,e=d.value),isNaN(e)||e instanceof Date||(g="number");var h,i,j;switch(g.toLowerCase()){case"week":if(h=/^(\d{4})-W(\d{2})$/,i=c.match(h),null===i)throw new Error("Invalid value for "+a+" attribute for week input. Should look like '2000-W33' http://www.w3.org/TR/html-markup/input.week.html#input.week.attrs.min");return j=e.match(h),j?b?i[1]j[1]||i[1]===j[1]&&i[2]>=j[2]:!1;case"month":if(h=/^(\d{4})-(\d{2})$/,i=c.match(h),null===i)throw new Error("Invalid value for "+a+" attribute for month input. Should look like '2000-03' http://www.w3.org/TR/html-markup/input.month.html#input.month.attrs.min");return j=e.match(h),j?b?i[1]j[1]||i[1]===j[1]&&i[2]>=j[2]:!1;case"number":case"range":return b?!isNaN(c)&&parseFloat(c)<=parseFloat(e):!isNaN(c)&&parseFloat(c)>=parseFloat(e);default:return b?e>=c:c>=e}}}function d(a,b,c){return b.validator(a(),void 0===c.params?!0:h(c.params))?!0:(a.setError(f.formatMessage(c.message||b.message,h(c.params),a)),!1)}function e(a,b,c){a.isValidating(!0);var d=function(d){var e=!1,g="";return a.__valid__()?(d.message?(e=d.isValid,g=d.message):e=d,e||(a.error(f.formatMessage(g||c.message||b.message,h(c.params),a)),a.__valid__(e)),void a.isValidating(!1)):void a.isValidating(!1)};f.utils.async(function(){b.validator(a(),void 0===c.params?!0:h(c.params),d)})}if("undefined"==typeof a)throw new Error("Knockout is required, please ensure it is loaded before loading this validation plug-in");a.validation=b;var f=a.validation,g=a.utils,h=g.unwrapObservable,i=g.arrayForEach,j=g.extend,k={registerExtenders:!0,messagesOnModified:!0,errorsAsTitle:!0,errorsAsTitleOnModified:!1,messageTemplate:null,insertMessages:!0,parseInputAttributes:!1,writeInputAttributes:!1,decorateInputElement:!1,decorateElementOnModified:!0,errorClass:null,errorElementClass:"validationElement",errorMessageClass:"validationMessage",allowHtmlMessages:!1,grouping:{deep:!1,observable:!0,live:!1},validate:{}},l=j({},k);l.html5Attributes=["required","pattern","min","max","step"],l.html5InputTypes=["email","number","date"],l.reset=function(){j(l,k)},f.configuration=l,f.utils=function(){var a=(new Date).getTime(),b={},c="__ko_validation__";return{isArray:function(a){return a.isArray||"[object Array]"===Object.prototype.toString.call(a)},isObject:function(a){return null!==a&&"object"==typeof a},isNumber:function(a){return!isNaN(a)},isObservableArray:function(a){return!!a&&"function"==typeof a.remove&&"function"==typeof a.removeAll&&"function"==typeof a.destroy&&"function"==typeof a.destroyAll&&"function"==typeof a.indexOf&&"function"==typeof a.replace},values:function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(a[c]);return b},getValue:function(a){return"function"==typeof a?a():a},hasAttribute:function(a,b){return null!==a.getAttribute(b)},getAttribute:function(a,b){return a.getAttribute(b)},setAttribute:function(a,b,c){return a.setAttribute(b,c)},isValidatable:function(a){return!!(a&&a.rules&&a.isValid&&a.isModified)},insertAfter:function(a,b){a.parentNode.insertBefore(b,a.nextSibling)},newId:function(){return a+=1},getConfigOptions:function(a){var b=f.utils.contextFor(a);return b||f.configuration},setDomData:function(a,d){var e=a[c];e||(a[c]=e=f.utils.newId()),b[e]=d},getDomData:function(a){var d=a[c];return d?b[d]:void 0},contextFor:function(a){switch(a.nodeType){case 1:case 8:var b=f.utils.getDomData(a);if(b)return b;if(a.parentNode)return f.utils.contextFor(a.parentNode)}return void 0},isEmptyVal:function(a){return void 0===a?!0:null===a?!0:""===a?!0:void 0},getOriginalElementTitle:function(a){var b=f.utils.getAttribute(a,"data-orig-title"),c=a.title,d=f.utils.hasAttribute(a,"data-orig-title");return d?b:c},async:function(a){window.setImmediate?window.setImmediate(a):window.setTimeout(a,0)},forEach:function(a,b){if(f.utils.isArray(a))return i(a,b);for(var c in a)a.hasOwnProperty(c)&&b(a[c],c)}}}();var m=function(){function b(a){i(a.subscriptions,function(a){a.dispose()}),a.subscriptions=[]}function c(a){a.options.deep&&(i(a.flagged,function(a){delete a.__kv_traversed}),a.flagged.length=0),a.options.live||b(a)}function d(a,d){d.validatables=[],b(d),e(a,d),c(d)}function e(b,c,d){var f=[],g=b.peek?b.peek():b;b.__kv_traversed!==!0&&(c.options.deep&&(b.__kv_traversed=!0,c.flagged.push(b)),d=void 0!==d?d:c.options.deep?1:-1,a.isObservable(b)&&(b.errors||n.isValidatable(b)||b.extend({validatable:!0}),c.validatables.push(b),c.options.live&&n.isObservableArray(b)&&c.subscriptions.push(b.subscribe(function(){c.graphMonitor.valueHasMutated()}))),g&&!g._destroy&&(n.isArray(g)?f=g:n.isObject(g)&&(f=n.values(g))),0!==d&&n.forEach(f,function(b){!b||b.nodeType||a.isComputed(b)&&!b.rules||e(b,c,d+1)}))}function k(a){var b=[];return i(a,function(a){n.isValidatable(a)&&!a.isValid()&&b.push(a.error.peek())}),b}var l=0,m=f.configuration,n=f.utils;return{init:function(a,b){l>0&&!b||(a=a||{},a.errorElementClass=a.errorElementClass||a.errorClass||m.errorElementClass,a.errorMessageClass=a.errorMessageClass||a.errorClass||m.errorMessageClass,j(m,a),m.registerExtenders&&f.registerExtenders(),l=1)},reset:f.configuration.reset,group:function(b,c){c=j(j({},m.grouping),c);var e={options:c,graphMonitor:a.observable(),flagged:[],subscriptions:[],validatables:[]},f=null;return f=c.observable?a.computed(function(){return e.graphMonitor(),d(b,e),k(e.validatables)}):function(){return d(b,e),k(e.validatables)},f.showAllMessages=function(a){void 0===a&&(a=!0),f.forEach(function(b){n.isValidatable(b)&&b.isModified(a)})},f.isAnyMessageShown=function(){var a;return a=!!f.find(function(a){return n.isValidatable(a)&&!a.isValid()&&a.isModified()})},f.filter=function(a){return a=a||function(){return!0},f(),g.arrayFilter(e.validatables,a)},f.find=function(a){return a=a||function(){return!0},f(),g.arrayFirst(e.validatables,a)},f.forEach=function(a){a=a||function(){},f(),i(e.validatables,a)},f.map=function(a){return a=a||function(a){return a},f(),g.arrayMap(e.validatables,a)},f._updateState=function(a){if(!n.isObject(a))throw new Error("An object is required.");return b=a,c.observable?void e.graphMonitor.valueHasMutated():(d(a,e),k(e.validatables))},f},formatMessage:function(a,b,c){if(n.isObject(b)&&b.typeAttr&&(b=b.value),"function"==typeof a)return a(b,c);var d=h(b);return null==d&&(d=[]),n.isArray(d)||(d=[d]),a.replace(/{(\d+)}/gi,function(a,b){return"undefined"!=typeof d[b]?d[b]:a})},addRule:function(a,b){a.extend({validatable:!0});var c=!!g.arrayFirst(a.rules(),function(a){return a.rule&&a.rule===b.rule});return c||a.rules.push(b),a},addAnonymousRule:function(a,b){void 0===b.message&&(b.message="Error"),b.onlyIf&&(b.condition=b.onlyIf),f.addRule(a,b)},addExtender:function(b){a.extenders[b]=function(a,c){return c&&(c.message||c.onlyIf)?f.addRule(a,{rule:b,message:c.message,params:n.isEmptyVal(c.params)?!0:c.params,condition:c.onlyIf}):f.addRule(a,{rule:b,params:c})}},registerExtenders:function(){if(m.registerExtenders)for(var b in f.rules)f.rules.hasOwnProperty(b)&&(a.extenders[b]||f.addExtender(b))},insertValidationMessage:function(a){var b=document.createElement("SPAN");return b.className=n.getConfigOptions(a).errorMessageClass,n.insertAfter(a,b),b},parseInputValidationAttributes:function(a,b){i(f.configuration.html5Attributes,function(c){if(n.hasAttribute(a,c)){var d=a.getAttribute(c)||!0;if("min"===c||"max"===c){var e=a.getAttribute("type");"undefined"!=typeof e&&e||(e="text"),d={typeAttr:e,value:d}}f.addRule(b(),{rule:c,params:d})}});var c=a.getAttribute("type");i(f.configuration.html5InputTypes,function(a){a===c&&f.addRule(b(),{rule:"date"===a?"dateISO":a,params:!0})})},writeInputValidationAttributes:function(b,c){var d=c();if(d&&d.rules){var e=d.rules();i(f.configuration.html5Attributes,function(c){var d=g.arrayFirst(e,function(a){return a.rule&&a.rule.toLowerCase()===c.toLowerCase()});d&&a.computed({read:function(){var e=a.unwrap(d.params);"pattern"===d.rule&&e instanceof RegExp&&(e=e.source),b.setAttribute(c,e)},disposeWhenNodeIsRemoved:b})}),e=null}},makeBindingHandlerValidatable:function(b){var c=a.bindingHandlers[b].init;a.bindingHandlers[b].init=function(b,d,e,f,g){return c(b,d,e,f,g),a.bindingHandlers.validationCore.init(b,d,e,f,g)}},setRules:function(b,c){var d=function(b,c){if(b&&c)for(var e in c)if(c.hasOwnProperty(e)){var g=c[e];if(b[e]){var i=b[e],j=h(i),k={},l={};for(var m in g)g.hasOwnProperty(m)&&(f.rules[m]?k[m]=g[m]:l[m]=g[m]);if(a.isObservable(i)&&i.extend(k),j&&n.isArray(j))for(var o=0;o0:!0)},message:"This field is required."},f.rules.min={validator:c("min"),message:"Please enter a value greater than or equal to {0}."},f.rules.max={validator:c("max"),message:"Please enter a value less than or equal to {0}."},f.rules.minLength={validator:function(a,b){if(f.utils.isEmptyVal(a))return!0;var c=f.utils.isNumber(a)?""+a:a;return c.length>=b},message:"Please enter at least {0} characters."},f.rules.maxLength={validator:function(a,b){if(f.utils.isEmptyVal(a))return!0;var c=f.utils.isNumber(a)?""+a:a;return c.length<=b},message:"Please enter no more than {0} characters."},f.rules.pattern={validator:function(a,b){return f.utils.isEmptyVal(a)||null!==a.toString().match(b)},message:"Please check this value."},f.rules.step={validator:function(a,b){if(f.utils.isEmptyVal(a)||"any"===b)return!0;var c=100*a%(100*b);return Math.abs(c)<1e-5||Math.abs(1-c)<1e-5},message:"The value must increment by {0}."},f.rules.email={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&/^((([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(a):!0},message:"Please enter a proper email address."},f.rules.date={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&!/Invalid|NaN/.test(new Date(a)):!0},message:"Please enter a proper date."},f.rules.dateISO={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&/^\d{4}[-/](?:0?[1-9]|1[012])[-/](?:0?[1-9]|[12][0-9]|3[01])$/.test(a):!0},message:"Please enter a proper date."},f.rules.number={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a):!0},message:"Please enter a number."},f.rules.digit={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&/^\d+$/.test(a):!0},message:"Please enter a digit."},f.rules.phoneUS={validator:function(a,b){return b?f.utils.isEmptyVal(a)?!0:"string"!=typeof a?!1:(a=a.replace(/\s+/g,""),b&&a.length>9&&a.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/)):!0},message:"Please specify a valid phone number."},f.rules.equal={validator:function(a,b){var c=b;return a===f.utils.getValue(c)},message:"Values must equal."},f.rules.notEqual={validator:function(a,b){var c=b;return a!==f.utils.getValue(c)},message:"Please choose another value."},f.rules.unique={validator:function(a,b){var c=f.utils.getValue(b.collection),d=f.utils.getValue(b.externalValue),e=0;return a&&c?(g.arrayFilter(c,function(c){a===(b.valueAccessor?b.valueAccessor(c):c)&&e++}),(d?1:2)>e):!0},message:"Please make sure the value is unique."},function(){f.registerExtenders()}(),a.bindingHandlers.validationCore=function(){return{init:function(b,c){var d=f.utils.getConfigOptions(b),e=c();if(d.parseInputAttributes&&f.utils.async(function(){f.parseInputValidationAttributes(b,c)}),d.insertMessages&&f.utils.isValidatable(e)){var g=f.insertValidationMessage(b);d.messageTemplate?a.renderTemplate(d.messageTemplate,{field:e},null,g,"replaceNode"):a.applyBindingsToNode(g,{validationMessage:e})}d.writeInputAttributes&&f.utils.isValidatable(e)&&f.writeInputValidationAttributes(b,c),d.decorateInputElement&&f.utils.isValidatable(e)&&a.applyBindingsToNode(b,{validationElement:e})}}}(),f.makeBindingHandlerValidatable("value"),f.makeBindingHandlerValidatable("checked"),a.bindingHandlers.textInput&&f.makeBindingHandlerValidatable("textInput"),f.makeBindingHandlerValidatable("selectedOptions"),a.bindingHandlers.validationMessage={update:function(b,c){var d=c(),e=f.utils.getConfigOptions(b),i=(h(d),!1),j=!1;if(null===d||"undefined"==typeof d)throw new Error("Cannot bind validationMessage to undefined value. data-bind expression: "+b.getAttribute("data-bind"));i=d.isModified&&d.isModified(),j=d.isValid&&d.isValid();var k=null;(!e.messagesOnModified||i)&&(k=j?null:d.error);var l=!e.messagesOnModified||i?!j:!1,m="none"!==b.style.display;e.allowHtmlMessages?g.setHtml(b,k):a.bindingHandlers.text.update(b,function(){return k}),m&&!l?b.style.display="none":!m&&l&&(b.style.display="")}},a.bindingHandlers.validationElement={update:function(b,c,d){var e=c(),g=f.utils.getConfigOptions(b),i=(h(e),!1),j=!1;if(null===e||"undefined"==typeof e)throw new Error("Cannot bind validationElement to undefined value. data-bind expression: "+b.getAttribute("data-bind"));i=e.isModified&&e.isModified(),j=e.isValid&&e.isValid();var k=function(){var a={},b=!g.decorateElementOnModified||i?!j:!1;return a[g.errorElementClass]=b,a};a.bindingHandlers.css.update(b,k,d),g.errorsAsTitle&&a.bindingHandlers.attr.update(b,function(){var a=!g.errorsAsTitleOnModified||i,c=f.utils.getOriginalElementTitle(b);return a&&!j?{title:e.error,"data-orig-title":c}:!a||j?{title:c,"data-orig-title":null}:void 0})}},a.bindingHandlers.validationOptions=function(){return{init:function(a,b){var c=h(b());if(c){var d=j({},f.configuration);j(d,c),f.utils.setDomData(a,d)}}}}(),a.extenders.validation=function(a,b){return i(f.utils.isArray(b)?b:[b],function(b){f.addAnonymousRule(a,b)}),a},a.extenders.validatable=function(b,c){if(f.utils.isObject(c)||(c={enable:c}),"enable"in c||(c.enable=!0),c.enable&&!f.utils.isValidatable(b)){var d=f.configuration.validate||{},e={throttleEvaluation:c.throttle||d.throttle};b.error=a.observable(null),b.rules=a.observableArray(),b.isValidating=a.observable(!1),b.__valid__=a.observable(!0),b.isModified=a.observable(!1),b.isValid=a.computed(b.__valid__),b.setError=function(a){var c=b.error.peek(),d=b.__valid__.peek();b.error(a),b.__valid__(!1),c===a||d||b.isValid.notifySubscribers()},b.clearError=function(){return b.error(null),b.__valid__(!0),b};var g=b.subscribe(function(){b.isModified(!0)}),h=a.computed(j({read:function(){b(),b.rules();return f.validateObservable(b),!0}},e));j(h,e),b._disposeValidation=function(){b.isValid.dispose(),b.rules.removeAll(),g.dispose(),h.dispose(),delete b.rules,delete b.error,delete b.isValid,delete b.isValidating,delete b.__valid__,delete b.isModified,delete b.setError,delete b.clearError,delete b._disposeValidation}}else c.enable===!1&&b._disposeValidation&&b._disposeValidation();return b},f.validateObservable=function(a){for(var b,c,g=0,h=a.rules(),i=h.length;i>g;g++)if(c=h[g],!c.condition||c.condition())if(b=c.rule?f.rules[c.rule]:c,b.async||c.async)e(a,b,c);else if(!d(a,b,c))return!1;return a.clearError(),!0};var n,o={};f.defineLocale=function(a,b){return a&&b?(o[a.toLowerCase()]=b,b):null},f.locale=function(a){if(a){if(a=a.toLowerCase(),!o.hasOwnProperty(a))throw new Error("Localization "+a+" has not been loaded.");f.localize(o[a]),n=a}return n},f.localize=function(a){var b=f.rules;for(var c in a)b.hasOwnProperty(c)&&(b[c].message=a[c])},function(){var a={},b=f.rules;for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c].message);f.defineLocale("en-us",a)}(),n="en-us",a.applyBindingsWithValidation=function(b,c,d){var e,g=document.body;c&&c.nodeType?(g=c,e=d):e=c,f.init(),e&&(e=j(j({},f.configuration),e),f.utils.setDomData(g,e)),a.applyBindings(b,g)};var p=a.applyBindings;a.applyBindings=function(a,b){f.init(),p(a,b)},a.validatedObservable=function(b,c){if(!c&&!f.utils.isObject(b))return a.observable(b).extend({validatable:!0});var d=a.observable(b);return d.errors=f.group(f.utils.isObject(b)?b:{},c),d.isValid=a.observable(0===d.errors().length),a.isObservable(d.errors)?d.errors.subscribe(function(a){d.isValid(0===a.length)}):a.computed(d.errors).subscribe(function(a){d.isValid(0===a.length)}),d.subscribe(function(a){f.utils.isObject(a)||(a={}),d.errors._updateState(a),d.isValid(0===d.errors().length)}),d}}); +!function(a){"function"==typeof require&&"object"==typeof exports&&"object"==typeof module?a(require("knockout"),exports):"function"==typeof define&&define.amd?define(["knockout","exports"],a):a(ko,ko.validation={})}(function(a,b){function c(a){var b="max"===a;return function(c,d){if(f.utils.isEmptyVal(c))return!0;var e,g;void 0===d.typeAttr?(g="text",e=d):(g=d.typeAttr,e=d.value),isNaN(e)||e instanceof Date||(g="number");var h,i,j;switch(g.toLowerCase()){case"week":if(h=/^(\d{4})-W(\d{2})$/,i=c.match(h),null===i)throw new Error("Invalid value for "+a+" attribute for week input. Should look like '2000-W33' http://www.w3.org/TR/html-markup/input.week.html#input.week.attrs.min");return j=e.match(h),j?b?i[1]j[1]||i[1]===j[1]&&i[2]>=j[2]:!1;case"month":if(h=/^(\d{4})-(\d{2})$/,i=c.match(h),null===i)throw new Error("Invalid value for "+a+" attribute for month input. Should look like '2000-03' http://www.w3.org/TR/html-markup/input.month.html#input.month.attrs.min");return j=e.match(h),j?b?i[1]j[1]||i[1]===j[1]&&i[2]>=j[2]:!1;case"number":case"range":return b?!isNaN(c)&&parseFloat(c)<=parseFloat(e):!isNaN(c)&&parseFloat(c)>=parseFloat(e);default:return b?e>=c:c>=e}}}function d(a,b,c){return b.validator(a(),void 0===c.params?!0:h(c.params))?null:f.formatMessage(c.message||b.message,h(c.params),a)}function e(a,b,c){a.__isValidatingAsync(!0);var d=function(d){var e=!1,g="";return a.__errorManual()||a.__errorSync()?void a.__isValidatingAsync(!1):(d.message?(e=d.isValid,g=d.message):e=d,e||a.__errorAsync(f.formatMessage(g||c.message||b.message,h(c.params),a)),void a.__isValidatingAsync(!1))};f.utils.async(function(){b.validator(a(),void 0===c.params?!0:h(c.params),d)})}if("undefined"==typeof a)throw new Error("Knockout is required, please ensure it is loaded before loading this validation plug-in");a.validation=b;var f=a.validation,g=a.utils,h=g.unwrapObservable,i=g.arrayForEach,j=g.extend,k={registerExtenders:!0,messagesOnModified:!0,errorsAsTitle:!0,errorsAsTitleOnModified:!1,messageTemplate:null,insertMessages:!0,parseInputAttributes:!1,writeInputAttributes:!1,decorateInputElement:!1,decorateElementOnModified:!0,errorClass:null,errorElementClass:"validationElement",errorMessageClass:"validationMessage",allowHtmlMessages:!1,grouping:{deep:!1,observable:!0,live:!1},validate:{setModifiedOnChange:!0}},l=j({},k);l.html5Attributes=["required","pattern","min","max","step"],l.html5InputTypes=["email","number","date"],l.reset=function(){j(l,k)},f.configuration=l,f.utils=function(){var a=(new Date).getTime(),b={},c="__ko_validation__";return{isArray:function(a){return a.isArray||"[object Array]"===Object.prototype.toString.call(a)},isObject:function(a){return null!==a&&"object"==typeof a},isNumber:function(a){return!isNaN(a)},isObservableArray:function(a){return!!a&&"function"==typeof a.remove&&"function"==typeof a.removeAll&&"function"==typeof a.destroy&&"function"==typeof a.destroyAll&&"function"==typeof a.indexOf&&"function"==typeof a.replace},values:function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(a[c]);return b},getValue:function(a){return"function"==typeof a?a():a},hasAttribute:function(a,b){return null!==a.getAttribute(b)},getAttribute:function(a,b){return a.getAttribute(b)},setAttribute:function(a,b,c){return a.setAttribute(b,c)},isValidatable:function(a){return!!(a&&a.rules&&a.isValid&&a.isModified)},insertAfter:function(a,b){a.parentNode.insertBefore(b,a.nextSibling)},newId:function(){return a+=1},getConfigOptions:function(a){var b=f.utils.contextFor(a);return b||f.configuration},setDomData:function(a,d){var e=a[c];e||(a[c]=e=f.utils.newId()),b[e]=d},getDomData:function(a){var d=a[c];return d?b[d]:void 0},contextFor:function(a){switch(a.nodeType){case 1:case 8:var b=f.utils.getDomData(a);if(b)return b;if(a.parentNode)return f.utils.contextFor(a.parentNode)}return void 0},isEmptyVal:function(a){return void 0===a?!0:null===a?!0:""===a?!0:void 0},getOriginalElementTitle:function(a){var b=f.utils.getAttribute(a,"data-orig-title"),c=a.title,d=f.utils.hasAttribute(a,"data-orig-title");return d?b:c},async:function(a){window.setImmediate?window.setImmediate(a):window.setTimeout(a,0)},forEach:function(a,b){if(f.utils.isArray(a))return i(a,b);for(var c in a)a.hasOwnProperty(c)&&b(a[c],c)}}}();var m=function(){function b(a){i(a.subscriptions,function(a){a.dispose()}),a.subscriptions=[]}function c(a){a.options.deep&&(i(a.flagged,function(a){delete a.__kv_traversed}),a.flagged.length=0),a.options.live||b(a)}function d(a,d){d.validatables=[],b(d),e(a,d),c(d)}function e(b,c,d){var f=[],g=b.peek?b.peek():b;b.__kv_traversed!==!0&&(c.options.deep&&(b.__kv_traversed=!0,c.flagged.push(b)),d=void 0!==d?d:c.options.deep?1:-1,a.isObservable(b)&&(b.errors||n.isValidatable(b)||b.extend({validatable:!0}),c.validatables.push(b),c.options.live&&n.isObservableArray(b)&&c.subscriptions.push(b.subscribe(function(){c.graphMonitor.valueHasMutated()}))),g&&!g._destroy&&(n.isArray(g)?f=g:n.isObject(g)&&(f=n.values(g))),0!==d&&n.forEach(f,function(b){!b||b.nodeType||a.isComputed(b)&&!b.rules||e(b,c,d+1)}))}function k(a){var b=[];return i(a,function(a){n.isValidatable(a)&&!a.isValid()&&b.push(a.error())}),b}var l=0,m=f.configuration,n=f.utils;return{init:function(a,b){l>0&&!b||(a=a||{},a.errorElementClass=a.errorElementClass||a.errorClass||m.errorElementClass,a.errorMessageClass=a.errorMessageClass||a.errorClass||m.errorMessageClass,j(m,a),m.registerExtenders&&f.registerExtenders(),l=1)},reset:f.configuration.reset,group:function(b,c){c=j(j({},m.grouping),c);var e={options:c,graphMonitor:a.observable(),flagged:[],subscriptions:[],validatables:[]},f=null;return f=c.observable?a.computed(function(){return e.graphMonitor(),d(b,e),k(e.validatables)}):function(){return d(b,e),k(e.validatables)},f.showAllMessages=function(a){void 0===a&&(a=!0),f.forEach(function(b){n.isValidatable(b)&&b.isModified(a)})},f.isAnyMessageShown=function(){var a;return a=!!f.find(function(a){return n.isValidatable(a)&&!a.isValid()&&a.isModified()})},f.filter=function(a){return a=a||function(){return!0},f(),g.arrayFilter(e.validatables,a)},f.find=function(a){return a=a||function(){return!0},f(),g.arrayFirst(e.validatables,a)},f.forEach=function(a){a=a||function(){},f(),i(e.validatables,a)},f.map=function(a){return a=a||function(a){return a},f(),g.arrayMap(e.validatables,a)},f._updateState=function(a){if(!n.isObject(a))throw new Error("An object is required.");return b=a,c.observable?void e.graphMonitor.valueHasMutated():(d(a,e),k(e.validatables))},f},formatMessage:function(a,b,c){if(n.isObject(b)&&b.typeAttr&&(b=b.value),"function"==typeof a)return a(b,c);var d=h(b);return null==d&&(d=[]),n.isArray(d)||(d=[d]),a.replace(/{(\d+)}/gi,function(a,b){return"undefined"!=typeof d[b]?d[b]:a})},addRule:function(a,b){a.extend({validatable:!0});var c=!!g.arrayFirst(a.rules(),function(a){return a.rule&&a.rule===b.rule});return c||a.rules.push(b),a},addAnonymousRule:function(a,b){void 0===b.message&&(b.message="Error"),b.onlyIf&&(b.condition=b.onlyIf),f.addRule(a,b)},addExtender:function(b){a.extenders[b]=function(a,c){return c&&(c.message||c.onlyIf)?f.addRule(a,{rule:b,message:c.message,params:n.isEmptyVal(c.params)?!0:c.params,condition:c.onlyIf}):f.addRule(a,{rule:b,params:c})}},registerExtenders:function(){if(m.registerExtenders)for(var b in f.rules)f.rules.hasOwnProperty(b)&&(a.extenders[b]||f.addExtender(b))},insertValidationMessage:function(a){var b=document.createElement("SPAN");return b.className=n.getConfigOptions(a).errorMessageClass,n.insertAfter(a,b),b},parseInputValidationAttributes:function(a,b){i(f.configuration.html5Attributes,function(c){if(n.hasAttribute(a,c)){var d=a.getAttribute(c)||!0;if("min"===c||"max"===c){var e=a.getAttribute("type");"undefined"!=typeof e&&e||(e="text"),d={typeAttr:e,value:d}}f.addRule(b(),{rule:c,params:d})}});var c=a.getAttribute("type");i(f.configuration.html5InputTypes,function(a){a===c&&f.addRule(b(),{rule:"date"===a?"dateISO":a,params:!0})})},writeInputValidationAttributes:function(b,c){var d=c();if(d&&d.rules){var e=d.rules();i(f.configuration.html5Attributes,function(c){var d=g.arrayFirst(e,function(a){return a.rule&&a.rule.toLowerCase()===c.toLowerCase()});d&&a.computed({read:function(){var e=a.unwrap(d.params);"pattern"===d.rule&&e instanceof RegExp&&(e=e.source),b.setAttribute(c,e)},disposeWhenNodeIsRemoved:b})}),e=null}},makeBindingHandlerValidatable:function(b){var c=a.bindingHandlers[b].init;a.bindingHandlers[b].init=function(b,d,e,f,g){return c(b,d,e,f,g),a.bindingHandlers.validationCore.init(b,d,e,f,g)}},setRules:function(b,c){var d=function(b,c){if(b&&c)for(var e in c)if(c.hasOwnProperty(e)){var g=c[e];if(b[e]){var i=b[e],j=h(i),k={},l={};for(var m in g)g.hasOwnProperty(m)&&(f.rules[m]?k[m]=g[m]:l[m]=g[m]);if(a.isObservable(i)&&i.extend(k),j&&n.isArray(j))for(var o=0;o0:!0)},message:"This field is required."},f.rules.min={validator:c("min"),message:"Please enter a value greater than or equal to {0}."},f.rules.max={validator:c("max"),message:"Please enter a value less than or equal to {0}."},f.rules.minLength={validator:function(a,b){if(f.utils.isEmptyVal(a))return!0;var c=f.utils.isNumber(a)?""+a:a;return c.length>=b},message:"Please enter at least {0} characters."},f.rules.maxLength={validator:function(a,b){if(f.utils.isEmptyVal(a))return!0;var c=f.utils.isNumber(a)?""+a:a;return c.length<=b},message:"Please enter no more than {0} characters."},f.rules.pattern={validator:function(a,b){return f.utils.isEmptyVal(a)||null!==a.toString().match(b)},message:"Please check this value."},f.rules.step={validator:function(a,b){if(f.utils.isEmptyVal(a)||"any"===b)return!0;var c=100*a%(100*b);return Math.abs(c)<1e-5||Math.abs(1-c)<1e-5},message:"The value must increment by {0}."},f.rules.email={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&/^((([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(a):!0},message:"Please enter a proper email address."},f.rules.date={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&!/Invalid|NaN/.test(new Date(a)):!0},message:"Please enter a proper date."},f.rules.dateISO={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&/^\d{4}[-\/](?:0?[1-9]|1[012])[-\/](?:0?[1-9]|[12][0-9]|3[01])$/.test(a):!0},message:"Please enter a proper date."},f.rules.number={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a):!0},message:"Please enter a number."},f.rules.digit={validator:function(a,b){return b?f.utils.isEmptyVal(a)||b&&/^\d+$/.test(a):!0},message:"Please enter a digit."},f.rules.phoneUS={validator:function(a,b){return b?f.utils.isEmptyVal(a)?!0:"string"!=typeof a?!1:(a=a.replace(/\s+/g,""),b&&a.length>9&&a.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/)):!0},message:"Please specify a valid phone number."},f.rules.equal={validator:function(a,b){var c=b;return a===f.utils.getValue(c)},message:"Values must equal."},f.rules.notEqual={validator:function(a,b){var c=b;return a!==f.utils.getValue(c)},message:"Please choose another value."},f.rules.unique={validator:function(a,b){var c=f.utils.getValue(b.collection),d=f.utils.getValue(b.externalValue),e=0;return a&&c?(g.arrayFilter(c,function(c){a===(b.valueAccessor?b.valueAccessor(c):c)&&e++}),(d?1:2)>e):!0},message:"Please make sure the value is unique."},function(){f.registerExtenders()}(),a.bindingHandlers.validationCore=function(){return{init:function(b,c){var d=f.utils.getConfigOptions(b),e=c();if(d.parseInputAttributes&&f.utils.async(function(){f.parseInputValidationAttributes(b,c)}),d.insertMessages&&f.utils.isValidatable(e)){var g=f.insertValidationMessage(b);d.messageTemplate?a.renderTemplate(d.messageTemplate,{field:e},null,g,"replaceNode"):a.applyBindingsToNode(g,{validationMessage:e})}d.writeInputAttributes&&f.utils.isValidatable(e)&&f.writeInputValidationAttributes(b,c),d.decorateInputElement&&f.utils.isValidatable(e)&&a.applyBindingsToNode(b,{validationElement:e})}}}(),f.makeBindingHandlerValidatable("value"),f.makeBindingHandlerValidatable("checked"),a.bindingHandlers.textInput&&f.makeBindingHandlerValidatable("textInput"),f.makeBindingHandlerValidatable("selectedOptions"),a.bindingHandlers.validationMessage={update:function(b,c){var d=c(),e=f.utils.getConfigOptions(b),i=(h(d),!1),j=!1;if(null===d||"undefined"==typeof d)throw new Error("Cannot bind validationMessage to undefined value. data-bind expression: "+b.getAttribute("data-bind"));i=d.isModified&&d.isModified(),j=d.isValid&&d.isValid();var k=null;(!e.messagesOnModified||i)&&(k=j?null:d.error);var l=!e.messagesOnModified||i?!j:!1,m="none"!==b.style.display;e.allowHtmlMessages?g.setHtml(b,k):a.bindingHandlers.text.update(b,function(){return k}),m&&!l?b.style.display="none":!m&&l&&(b.style.display="")}},a.bindingHandlers.validationElement={update:function(b,c,d){var e=c(),g=f.utils.getConfigOptions(b),i=(h(e),!1),j=!1;if(null===e||"undefined"==typeof e)throw new Error("Cannot bind validationElement to undefined value. data-bind expression: "+b.getAttribute("data-bind"));i=e.isModified&&e.isModified(),j=e.isValid&&e.isValid();var k=function(){var a={},b=!g.decorateElementOnModified||i?!j:!1;return a[g.errorElementClass]=b,a};a.bindingHandlers.css.update(b,k,d),g.errorsAsTitle&&a.bindingHandlers.attr.update(b,function(){var a=!g.errorsAsTitleOnModified||i,c=f.utils.getOriginalElementTitle(b);return a&&!j?{title:e.error,"data-orig-title":c}:!a||j?{title:c,"data-orig-title":null}:void 0})}},a.bindingHandlers.validationOptions=function(){return{init:function(a,b){var c=h(b());if(c){var d=j({},f.configuration);j(d,c),f.utils.setDomData(a,d)}}}}(),a.extenders.validation=function(a,b){return i(f.utils.isArray(b)?b:[b],function(b){f.addAnonymousRule(a,b)}),a},a.extenders.validatable=function(b,c){if(f.utils.isObject(c)||(c={enable:c}),c=j(j({enable:!0},f.configuration.validate),c),c.enable&&!f.utils.isValidatable(b)){var g={throttleEvaluation:c.throttle};b.__errorManual=a.observable(null),b.__errorSync=a.pureComputed(function(){var a,c,g,h=b.rules(),i=h.length,j=null;for(a=0;i>a;a++)if(g=h[a],(!g.condition||g.condition())&&(c=g.rule?f.rules[g.rule]:g,!c.async&&!g.async&&(j=d(b,c,g))))return j;return function(){for(a=0;i>a;a++)g=h[a],(!g.condition||g.condition())&&(c=g.rule?f.rules[g.rule]:g,(c.async||g.async)&&e(b,c,g))}(),null}),j(b.__errorSync,g),b.__errorAsync=a.observable(null),b.__isValidatingAsync=a.observable(!1),b.error=a.pureComputed(function(){return b.__errorManual()||b.__errorSync()||b.__errorAsync()||null}),b.isValid=a.pureComputed(function(){return!b.error()}),b.isValidating=a.pureComputed(b.__isValidatingAsync),b.rules=a.observableArray(),b.isModified=a.observable(!1),b.setError=function(a){return b.__errorManual(a),b},b.clearError=function(){return b.__errorManual(null),b};var h;c.setModifiedOnChange&&(h=b.subscribe(function(){b.isModified(!0)})),b._disposeValidation=function(){b.rules.removeAll(),b.clearError(),b.__errorSync.dispose(),b.error.dispose(),b.isValid.dispose(),b.isValidating.dispose(),h&&h.dispose(),delete b.__errorManual,delete b.__errorSync,delete b.__errorAsync,delete b.__isValidatingAsync,delete b.error,delete b.isValid,delete b.isValidating,delete b.rules,delete b.isModified,delete b.setError,delete b.clearError,delete b._disposeValidation}}else c.enable===!1&&b._disposeValidation&&b._disposeValidation();return b},f.validateObservable=function(a){return a.isValid()};var n,o={};f.defineLocale=function(a,b){return a&&b?(o[a.toLowerCase()]=b,b):null},f.locale=function(a){if(a){if(a=a.toLowerCase(),!o.hasOwnProperty(a))throw new Error("Localization "+a+" has not been loaded.");f.localize(o[a]),n=a}return n},f.localize=function(a){var b=f.rules;for(var c in a)b.hasOwnProperty(c)&&(b[c].message=a[c])},function(){var a={},b=f.rules;for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c].message);f.defineLocale("en-us",a)}(),n="en-us",a.applyBindingsWithValidation=function(b,c,d){var e,g=document.body;c&&c.nodeType?(g=c,e=d):e=c,f.init(),e&&(e=j(j({},f.configuration),e),f.utils.setDomData(g,e)),a.applyBindings(b,g)};var p=a.applyBindings;a.applyBindings=function(a,b){f.init(),p(a,b)},a.validatedObservable=function(b,c){if(!c&&!f.utils.isObject(b))return a.observable(b).extend({validatable:!0});var d=a.observable(b);return d.errors=f.group(f.utils.isObject(b)?b:{},c),d.isValid=a.observable(0===d.errors().length),a.isObservable(d.errors)?d.errors.subscribe(function(a){d.isValid(0===a.length)}):a.computed(d.errors).subscribe(function(a){d.isValid(0===a.length)}),d.subscribe(function(a){f.utils.isObject(a)||(a={}),d.errors._updateState(a),d.isValid(0===d.errors().length)}),d}}); //# sourceMappingURL=knockout.validation.min.js.map \ No newline at end of file diff --git a/dist/knockout.validation.min.js.map b/dist/knockout.validation.min.js.map index 7483297e..13302ba4 100644 --- a/dist/knockout.validation.min.js.map +++ b/dist/knockout.validation.min.js.map @@ -1 +1 @@ -{"version":3,"file":"knockout.validation.min.js","sources":["knockout.validation.js"],"names":["factory","require","exports","module","define","ko","validation","minMaxValidatorFactory","validatorName","isMaxValidation","val","options","kv","utils","isEmptyVal","comparisonValue","type","undefined","typeAttr","value","isNaN","Date","regex","valMatches","comparisonValueMatches","toLowerCase","match","Error","parseFloat","validateSync","observable","rule","ctx","validator","params","unwrap","setError","formatMessage","message","validateAsync","isValidating","callBack","valObj","isValid","msg","__valid__","error","async","koUtils","unwrapObservable","forEach","arrayForEach","extend","defaults","registerExtenders","messagesOnModified","errorsAsTitle","errorsAsTitleOnModified","messageTemplate","insertMessages","parseInputAttributes","writeInputAttributes","decorateInputElement","decorateElementOnModified","errorClass","errorElementClass","errorMessageClass","allowHtmlMessages","grouping","deep","live","validate","configuration","html5Attributes","html5InputTypes","reset","seedId","getTime","domData","domDataKey","isArray","o","Object","prototype","toString","call","isObject","isNumber","isObservableArray","instance","values","r","i","hasOwnProperty","push","getValue","hasAttribute","node","attr","getAttribute","element","setAttribute","isValidatable","rules","isModified","insertAfter","newNode","parentNode","insertBefore","nextSibling","newId","getConfigOptions","contextFor","setDomData","data","key","getDomData","nodeType","context","getOriginalElementTitle","savedOriginalTitle","currentTitle","title","hasSavedOriginalTitle","expr","window","setImmediate","setTimeout","object","callback","prop","api","cleanUpSubscriptions","subscriptions","subscription","dispose","flagged","obj","__kv_traversed","length","runTraversal","validatables","traverseGraph","level","objValues","peek","isObservable","errors","validatable","subscribe","graphMonitor","valueHasMutated","_destroy","isComputed","collectErrors","array","isInitialized","init","force","group","result","computed","showAllMessages","show","isAnyMessageShown","invalidAndModifiedPresent","find","filter","predicate","arrayFilter","arrayFirst","map","mapping","item","arrayMap","_updateState","newValue","replacements","replace","index","addRule","hasRule","addAnonymousRule","ruleObj","onlyIf","condition","addExtender","ruleName","extenders","insertValidationMessage","span","document","createElement","className","parseInputValidationAttributes","valueAccessor","currentType","writeInputValidationAttributes","contexts","read","RegExp","source","disposeWhenNodeIsRemoved","makeBindingHandlerValidatable","handlerName","bindingHandlers","allBindingsAccessor","viewModel","bindingContext","setRules","target","definition","ruleDefinitions","targetValue","unwrappedTargetValue","nonRules","required","testVal","String","trim","minLength","normalizedVal","maxLength","step","dif","Math","abs","test","phoneNumber","otherValue","c","collection","external","externalValue","counter","config","validationMessageElement","renderTemplate","field","applyBindingsToNode","validationMessage","validationElement","textInput","update","obsv","isVisible","isCurrentlyVisible","style","display","setHtml","text","cssSettingsAccessor","css","shouldShow","hasModification","data-orig-title","newConfig","enable","validationOptions","throttleEvaluation","throttle","observableArray","previousError","previousIsValid","notifySubscribers","clearError","h_change","h_obsValidationTrigger","validateObservable","_disposeValidation","removeAll","ruleContexts","len","_currentLocale","_locales","defineLocale","name","locale","localize","msgTranslations","localeData","applyBindingsWithValidation","rootNode","body","applyBindings","origApplyBindings","validatedObservable","initialValue"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"knockout.validation.min.js","sources":["knockout.validation.js"],"names":["factory","require","exports","module","define","ko","validation","minMaxValidatorFactory","validatorName","isMaxValidation","val","options","kv","utils","isEmptyVal","comparisonValue","type","undefined","typeAttr","value","isNaN","Date","regex","valMatches","comparisonValueMatches","toLowerCase","match","Error","parseFloat","validateSync","observable","rule","ctx","validator","params","unwrap","formatMessage","message","validateAsync","__isValidatingAsync","callback","valObj","isValid","msg","__errorManual","__errorSync","__errorAsync","async","koUtils","unwrapObservable","forEach","arrayForEach","extend","defaults","registerExtenders","messagesOnModified","errorsAsTitle","errorsAsTitleOnModified","messageTemplate","insertMessages","parseInputAttributes","writeInputAttributes","decorateInputElement","decorateElementOnModified","errorClass","errorElementClass","errorMessageClass","allowHtmlMessages","grouping","deep","live","validate","setModifiedOnChange","configuration","html5Attributes","html5InputTypes","reset","seedId","getTime","domData","domDataKey","isArray","o","Object","prototype","toString","call","isObject","isNumber","isObservableArray","instance","values","r","i","hasOwnProperty","push","getValue","hasAttribute","node","attr","getAttribute","element","setAttribute","isValidatable","rules","isModified","insertAfter","newNode","parentNode","insertBefore","nextSibling","newId","getConfigOptions","contextFor","setDomData","data","key","getDomData","nodeType","context","getOriginalElementTitle","savedOriginalTitle","currentTitle","title","hasSavedOriginalTitle","expr","window","setImmediate","setTimeout","object","prop","api","cleanUpSubscriptions","subscriptions","subscription","dispose","flagged","obj","__kv_traversed","length","runTraversal","validatables","traverseGraph","level","objValues","peek","isObservable","errors","validatable","subscribe","graphMonitor","valueHasMutated","_destroy","isComputed","collectErrors","array","error","isInitialized","init","force","group","result","computed","showAllMessages","show","isAnyMessageShown","invalidAndModifiedPresent","find","filter","predicate","arrayFilter","arrayFirst","map","mapping","item","arrayMap","_updateState","newValue","replacements","replace","index","addRule","hasRule","addAnonymousRule","ruleObj","onlyIf","condition","addExtender","ruleName","extenders","insertValidationMessage","span","document","createElement","className","parseInputValidationAttributes","valueAccessor","currentType","writeInputValidationAttributes","contexts","read","RegExp","source","disposeWhenNodeIsRemoved","makeBindingHandlerValidatable","handlerName","bindingHandlers","allBindingsAccessor","viewModel","bindingContext","setRules","target","definition","ruleDefinitions","targetValue","unwrappedTargetValue","nonRules","required","testVal","String","trim","minLength","normalizedVal","maxLength","step","dif","Math","abs","test","phoneNumber","otherValue","c","collection","external","externalValue","counter","config","validationMessageElement","renderTemplate","field","applyBindingsToNode","validationMessage","validationElement","textInput","update","obsv","isVisible","isCurrentlyVisible","style","display","setHtml","text","cssSettingsAccessor","css","shouldShow","hasModification","data-orig-title","newConfig","enable","validationOptions","throttleEvaluation","throttle","pureComputed","ruleContexts","len","isValidating","observableArray","setError","clearError","h_change","_disposeValidation","removeAll","validateObservable","_currentLocale","_locales","defineLocale","name","locale","localize","msgTranslations","localeData","applyBindingsWithValidation","rootNode","body","applyBindings","origApplyBindings","validatedObservable","initialValue"],"mappings":"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"} \ No newline at end of file diff --git a/src/api.js b/src/api.js index d9c8ad02..e6f270ad 100644 --- a/src/api.js +++ b/src/api.js @@ -90,9 +90,7 @@ ko.utils.arrayForEach(array, function (observable) { // Do not collect validatedObservable errors if (utils.isValidatable(observable) && !observable.isValid()) { - // Use peek because we don't want a dependency for 'error' property because it - // changes before 'isValid' does. (Issue #99) - errors.push(observable.error.peek()); + errors.push(observable.error()); } }); return errors; diff --git a/src/configuration.js b/src/configuration.js index ac21f170..acd888e2 100644 --- a/src/configuration.js +++ b/src/configuration.js @@ -21,6 +21,7 @@ var defaults = { live: false //react to changes to observableArrays if observable === true }, validate: { + setModifiedOnChange: true, // enables setting `isModified(true)` when observable changes // throttle: 10 } }; diff --git a/src/extenders.js b/src/extenders.js index 4f69493b..873f365e 100644 --- a/src/extenders.js +++ b/src/extenders.js @@ -20,6 +20,68 @@ ko.extenders['validation'] = function (observable, rules) { // allow single rule return observable; }; +function validateSync(observable, rule, ctx) { + //Execute the validator and see if its valid + if (!rule.validator(observable(), (ctx.params === undefined ? true : ko.utils.unwrapObservable(ctx.params)))) { // default param is true, eg. required = true + + //not valid, so format the error message and stick it in the 'error' variable + return ko.validation.formatMessage( + ctx.message || rule.message, + ko.utils.unwrapObservable(ctx.params), + observable + ); + } + return null; +} + +function validateAsync(observable, rule, ctx) { + observable.__isValidatingAsync(true); + + var callback = function (valObj) { + var isValid = false, + msg = ''; + + if (observable.__errorManual() || observable.__errorSync()) { + + // since we're returning early, make sure we turn this off + observable.__isValidatingAsync(false); + + return; //if its already NOT valid, don't add to that + } + + //we were handed back a complex object + if (valObj['message']) { + isValid = valObj.isValid; + msg = valObj.message; + } else { + isValid = valObj; + } + + if (!isValid) { + //not valid, so format the error message and stick it in the 'error' variable + observable.__errorAsync( + ko.validation.formatMessage( + msg || ctx.message || rule.message, + ko.utils.unwrapObservable(ctx.params), + observable + ) + ); + } + + // tell it that we're done + observable.__isValidatingAsync(false); + }; + + ko.validation.utils.async(function() { + //fire the validator and hand it the callback + rule.validator( + observable(), + ctx.params === undefined ? true : ko.utils.unwrapObservable(ctx.params), + callback + ); + }); +} + //This is the extender that makes a Knockout Observable also 'Validatable' //examples include: // 1. var test = ko.observable('something').extend({validatable: true}); @@ -32,17 +94,100 @@ ko.extenders['validatable'] = function (observable, options) { options = { enable: options }; } - if (!('enable' in options)) { - options.enable = true; - } + options = ko.utils.extend(ko.utils.extend({ + enable: true, + }, ko.validation.configuration.validate), options); if (options.enable && !ko.validation.utils.isValidatable(observable)) { - var config = ko.validation.configuration.validate || {}; var validationOptions = { - throttleEvaluation : options.throttle || config.throttle + throttleEvaluation : options.throttle, }; - observable.error = ko.observable(null); // holds the error message, we only need one since we stop processing validators when one is invalid + // holds an error set by setError (and cleared by clearError) + observable.__errorManual = ko.observable(null); + + // holds an error from synchronous validation rules + observable.__errorSync = ko.pureComputed(function () { + var i, + rule, // the rule validator to execute + ctx, // the current Rule Context for the loop + ruleContexts = observable.rules(), //cache for iterator + len = ruleContexts.length, //cache for iterator + error = null; + + for (i = 0; i < len; i++) { + + //get the Rule Context info to give to the core Rule + ctx = ruleContexts[i]; + + // checks an 'onlyIf' condition + if (ctx.condition && !ctx.condition()) { + continue; + } + + //get the core Rule to use for validation + rule = ctx.rule ? ko.validation.rules[ctx.rule] : ctx; + + if (rule['async'] || ctx['async']) { + // skip async rules + continue; + + } else { + //run normal sync validation + error = validateSync(observable, rule, ctx); + if (error) { + return error; //break out of the loop + } + } + } + + // all sync rules are satisfied, fire async validation + (function () { + for (i = 0; i < len; i++) { + + //get the Rule Context info to give to the core Rule + ctx = ruleContexts[i]; + + // checks an 'onlyIf' condition + if (ctx.condition && !ctx.condition()) { + continue; + } + + //get the core Rule to use for validation + rule = ctx.rule ? ko.validation.rules[ctx.rule] : ctx; + + if (rule['async'] || ctx['async']) { + validateAsync(observable, rule, ctx); + + } else { + // skip sync rules + continue; + } + } + }()); + + return null; + }); + + ko.utils.extend(observable.__errorSync, validationOptions); + + // holds an error from asynchronous validation rules + observable.__errorAsync = ko.observable(null); + // is async validation currently running + observable.__isValidatingAsync = ko.observable(false); + + // holds the overall error message + observable.error = ko.pureComputed(function () { + return observable.__errorManual() || observable.__errorSync() || observable.__errorAsync() || null; + }); + + // readonly overall validity status + observable.isValid = ko.pureComputed(function () { + return !observable.error(); + }); + + // readonly "async validation is running" + observable.isValidating = ko.pureComputed(observable.__isValidatingAsync); // observable.rules: // ObservableArray of Rule Contexts, where a Rule Context is simply the name of a rule and the params to supply to it @@ -50,75 +195,54 @@ ko.extenders['validatable'] = function (observable, options) { // Rule Context = { rule: '', params: '', message: '' } observable.rules = ko.observableArray(); //holds the rule Contexts to use as part of validation - //in case async validation is occurring - observable.isValidating = ko.observable(false); - - //the true holder of whether the observable is valid or not - observable.__valid__ = ko.observable(true); - + // this could also be called `isMessageVisible` observable.isModified = ko.observable(false); - // a semi-protected observable - observable.isValid = ko.computed(observable.__valid__); - //manually set error state observable.setError = function (error) { - var previousError = observable.error.peek(); - var previousIsValid = observable.__valid__.peek(); - - observable.error(error); - observable.__valid__(false); - - if (previousError !== error && !previousIsValid) { - // if the observable was not valid before then isValid will not mutate, - // hence causing any grouping to not display the latest error. - observable.isValid.notifySubscribers(); - } + observable.__errorManual(error); + return observable; }; //manually clear error state observable.clearError = function () { - observable.error(null); - observable.__valid__(true); + observable.__errorManual(null); return observable; }; - //subscribe to changes in the observable - var h_change = observable.subscribe(function () { - observable.isModified(true); - }); - - // we use a computed here to ensure that anytime a dependency changes, the - // validation logic evaluates - var h_obsValidationTrigger = ko.computed(ko.utils.extend({ - read: function () { - var obs = observable(), - ruleContexts = observable.rules(); + var h_change; + if (options.setModifiedOnChange) { + //subscribe to changes in the observable + h_change = observable.subscribe(function () { + observable.isModified(true); + }); + } - ko.validation.validateObservable(observable); + observable._disposeValidation = function () { + // first dispose of the subscriptions + observable.rules.removeAll(); + observable.clearError(); + observable.__errorSync.dispose(); + observable.error.dispose(); + observable.isValid.dispose(); + observable.isValidating.dispose(); - return true; + if (h_change) { + h_change.dispose(); } - }, validationOptions)); - - ko.utils.extend(h_obsValidationTrigger, validationOptions); - observable._disposeValidation = function () { - //first dispose of the subscriptions - observable.isValid.dispose(); - observable.rules.removeAll(); - h_change.dispose(); - h_obsValidationTrigger.dispose(); - - delete observable['rules']; - delete observable['error']; - delete observable['isValid']; - delete observable['isValidating']; - delete observable['__valid__']; - delete observable['isModified']; - delete observable['setError']; - delete observable['clearError']; - delete observable['_disposeValidation']; + delete observable.__errorManual; + delete observable.__errorSync; + delete observable.__errorAsync; + delete observable.__isValidatingAsync; + delete observable.error; + delete observable.isValid; + delete observable.isValidating; + delete observable.rules; + delete observable.isModified; + delete observable.setError; + delete observable.clearError; + delete observable._disposeValidation; }; } else if (options.enable === false && observable._disposeValidation) { observable._disposeValidation(); @@ -126,95 +250,7 @@ ko.extenders['validatable'] = function (observable, options) { return observable; }; -function validateSync(observable, rule, ctx) { - //Execute the validator and see if its valid - if (!rule.validator(observable(), (ctx.params === undefined ? true : ko.utils.unwrapObservable(ctx.params)))) { // default param is true, eg. required = true - - //not valid, so format the error message and stick it in the 'error' variable - observable.setError(ko.validation.formatMessage( - ctx.message || rule.message, - ko.utils.unwrapObservable(ctx.params), - observable)); - return false; - } else { - return true; - } -} - -function validateAsync(observable, rule, ctx) { - observable.isValidating(true); - - var callBack = function (valObj) { - var isValid = false, - msg = ''; - - if (!observable.__valid__()) { - - // since we're returning early, make sure we turn this off - observable.isValidating(false); - - return; //if its already NOT valid, don't add to that - } - - //we were handed back a complex object - if (valObj['message']) { - isValid = valObj.isValid; - msg = valObj.message; - } else { - isValid = valObj; - } - - if (!isValid) { - //not valid, so format the error message and stick it in the 'error' variable - observable.error(ko.validation.formatMessage( - msg || ctx.message || rule.message, - ko.utils.unwrapObservable(ctx.params), - observable)); - observable.__valid__(isValid); - } - - // tell it that we're done - observable.isValidating(false); - }; - - ko.validation.utils.async(function() { - //fire the validator and hand it the callback - rule.validator(observable(), ctx.params === undefined ? true : ko.utils.unwrapObservable(ctx.params), callBack); - }); -} - ko.validation.validateObservable = function (observable) { - var i = 0, - rule, // the rule validator to execute - ctx, // the current Rule Context for the loop - ruleContexts = observable.rules(), //cache for iterator - len = ruleContexts.length; //cache for iterator - - for (; i < len; i++) { - - //get the Rule Context info to give to the core Rule - ctx = ruleContexts[i]; - - // checks an 'onlyIf' condition - if (ctx.condition && !ctx.condition()) { - continue; - } - - //get the core Rule to use for validation - rule = ctx.rule ? ko.validation.rules[ctx.rule] : ctx; - - if (rule['async'] || ctx['async']) { - //run async validation - validateAsync(observable, rule, ctx); - - } else { - //run normal sync validation - if (!validateSync(observable, rule, ctx)) { - return false; //break out of the loop - } - } - } - //finally if we got this far, make the observable valid again! - observable.clearError(); - return true; + return observable.isValid(); }; + diff --git a/test/api-tests.js b/test/api-tests.js index 24fbcb9b..286e7e37 100644 --- a/test/api-tests.js +++ b/test/api-tests.js @@ -38,7 +38,7 @@ QUnit.test('clearError clears manually-specified error', function(assert) { assert.equal(testObj.error(), null); }); -QUnit.test('clearError clears automatic errors', function(assert) { +QUnit.test('clearError does not clear automatic errors', function(assert) { var testObj = ko.observable(5); testObj.extend({ min: 6 }); @@ -48,9 +48,9 @@ QUnit.test('clearError clears automatic errors', function(assert) { var result = testObj.clearError(); assert.equal(testObj, result, 'The result should be returned to support chaining'); - //check validation was cleared - assert.ok(testObj.isValid()); - assert.equal(testObj.error(), null); + //check validation was not cleared + assert.equal(testObj.isValid(), false); + assert.notEqual(testObj.error(), null); }); //#endregion @@ -419,7 +419,7 @@ QUnit.test('Issue #209 - Grouping works when multiple rules are defined - Observ vm.one('abc'); - assert.equal(vm.one.error(), 'Please enter a digit.'); + assert.equal(vm.one.error(), 'Please enter a digit.', 'observable has expected error'); assert.strictEqual(vm.one.isValid(), false, 'observable is not valid'); assert.deepEqual(errors(), ['Please enter a digit.'], 'Grouping correctly finds 1 invalid property'); }); @@ -743,6 +743,82 @@ QUnit.test('validatedObservable works when changing from undefined to object', f assert.equal(testObj.errors()[0], 'This field is required.', 'message is correct'); }); +QUnit.test('validatedObservable by default is automatically isModified whenever it\'s value changes', function (assert) { + var testObj = ko.observable().extend({ validatable: true }); + + assert.strictEqual(testObj.isModified(), false, 'observable is not modified'); + + testObj(1); + + assert.strictEqual(testObj.isModified(), true, 'observable is modified'); +}); + +QUnit.test('validatedObservable isModified(true) on change can be disabled using global configuration', function (assert) { + ko.validation.init({ + validate: { + setModifiedOnChange: false + } + }, true); + + var testObj = ko.observable().extend({ validatable: true }); + + assert.strictEqual(testObj.isModified(), false, 'observable is not modified'); + + testObj(1); + + assert.strictEqual(testObj.isModified(), false, 'observable is not modified'); +}); + +QUnit.test('validatedObservable isModified(true) on change can be disabled using local configuration', function (assert) { + var testObj = ko.observable().extend({ + validatable: { + setModifiedOnChange: false + } + }); + + assert.strictEqual(testObj.isModified(), false, 'observable is not modified'); + + testObj(1); + + assert.strictEqual(testObj.isModified(), false, 'observable is not modified'); +}); + +QUnit.test('Issue #622 - validatable extender does not force pureComputed evaluation until necessary', function (assert) { + ko.validation.init({ + validate: { + setModifiedOnChange: false + } + }, true); + + var wasComputed = false; + + var pure = ko.pureComputed(function () { + wasComputed = true; + }); + + assert.strictEqual(wasComputed, false, 'not evaluating on creation'); + + pure.extend({ + validatable: true + }); + + assert.strictEqual(wasComputed, false, 'not evaluating on extend validatable'); + + pure.isValid(); + + assert.strictEqual(wasComputed, false, 'not evaluating on isValid when rules do not read value'); + + pure.extend({ + required: true + }); + + assert.strictEqual(wasComputed, false, 'not evaluating on extend required'); + + pure.isValid(); + + assert.strictEqual(wasComputed, true, 'evaluating on isValid when rules do read value'); +}); + //#endregion //#region setRules Tests @@ -913,14 +989,6 @@ QUnit.test('can be throttled using global configuration', function(assert) { var done = assert.async(); assert.expect(0); - var _validateObservable = ko.validation.validateObservable; - ko.validation.validateObservable = function() { - var result = _validateObservable.apply(this, arguments); - ko.validation.validateObservable = _validateObservable; - done(); - return result; - }; - ko.validation.init({ validate: { throttle: 10 @@ -928,6 +996,12 @@ QUnit.test('can be throttled using global configuration', function(assert) { }, true); var observable = ko.observable().extend({ validatable: true }); + + var subscription = observable.isValid.subscribe(function () { + subscription.dispose(); + done(); + }); + observable('1'); observable.extend({ minLength: 2 }); }); @@ -936,20 +1010,17 @@ QUnit.test('can be throttled using using local configuration', function(assert) var done = assert.async(); assert.expect(0); - var _validateObservable = ko.validation.validateObservable; - ko.validation.validateObservable = function() { - var result = _validateObservable.apply(this, arguments); - ko.validation.validateObservable = _validateObservable; - done(); - return result; - }; - var observable = ko.observable().extend({ validatable: { throttle: 10 } }); + var subscription = observable.isValid.subscribe(function () { + subscription.dispose(); + done(); + }); + observable.extend({ minLength: 2 }); observable('1'); }); diff --git a/test/validation-tests.js b/test/validation-tests.js index d63d1eea..9d8740db 100644 --- a/test/validation-tests.js +++ b/test/validation-tests.js @@ -333,6 +333,8 @@ QUnit.test('Async Rule Is Valid Test', function(assert) { var testObj = ko.observable(5); testObj.extend({ mustEqualAsync: 5 }); + + testObj.isValid(); }); QUnit.test('Async Rule Is NOT Valid Test', function(assert) { @@ -359,6 +361,8 @@ QUnit.test('Async Rule Is NOT Valid Test', function(assert) { var testObj = ko.observable(4); testObj.extend({ mustEqualAsync: 5 }); + + testObj.isValid(); }); QUnit.test('Issue #341 Async Rule that is not valid and returns synchronously should be invalid after callback', function (assert) { @@ -378,6 +382,8 @@ QUnit.test('Issue #341 Async Rule that is not valid and returns synchronously sh var testObj = ko.observable(0); testObj.extend({ immediatelyFalse: true }); + + testObj.isValid(); }); //#endregion @@ -430,6 +436,8 @@ QUnit.test('message parameter receives params and observable when async', functi ko.validation.registerExtenders(); //make sure the new rule is registered testObj.extend({ mustEqualAsync: 5 }); + + testObj.isValid(); }); //#endregion diff --git a/test/validation-ui-tests.js b/test/validation-ui-tests.js index 63d82f6d..7c708cf1 100644 --- a/test/validation-ui-tests.js +++ b/test/validation-ui-tests.js @@ -644,7 +644,7 @@ QUnit.test('Issue #519 - validationElement can be applied before element is vali vm.testObj.extend({ validatable: false }); assert.ok(!ko.validation.utils.isValidatable(vm.testObj)); - assert.strictEqual($("#testElement").attr("title"), undefined); + assert.equal($("#testElement").attr("title"), false); }); QUnit.test('Issue #519 - validationMessage can be applied before element is validatable', function(assert) {