diff --git a/dist/simple-react-validator.js b/dist/simple-react-validator.js index 577829d..a8647f1 100644 --- a/dist/simple-react-validator.js +++ b/dist/simple-react-validator.js @@ -83,6 +83,9 @@ function () { isBlank: function isBlank(value) { return typeof value === 'undefined' || value === null || value === ''; }, + isAsync: function isAsync(rule, rules) { + return rules[rule].hasOwnProperty('asyncRule'); + }, normalizeValues: function normalizeValues(value, validation) { return [this.valueOrEmptyString(value), this.getValidation(validation), this.getOptions(validation)]; }, @@ -162,6 +165,7 @@ function () { this.fields = {}; this.visibleFields = []; this.errorMessages = {}; + this.asyncValidators = {}; this.messagesShown = false; this.rules = _objectSpread({ accepted: { @@ -468,6 +472,37 @@ function () { return true; } + }, { + key: "asyncValid", + value: function asyncValid(completion) { + this.failedAsyncValidator = null; + if (!this.allValid()) return completion.fail(); + if (Object.keys(this.asyncValidators).length === 0) return completion.pass(); + this.currentAsyncValidator = Object.keys(this.asyncValidators)[0]; + var validator = this.asyncValidators[this.currentAsyncValidator]; + validator.rules[validator.rule].asyncRule(validator.value, validator.params, this, completion); + } + }, { + key: "pass", + value: function pass(completion) { + var keys = Object.keys(this.asyncValidators); + var index = keys.indexOf(this.currentAsyncValidator); + + if (index >= keys.length - 1) { + return completion.pass(); + } else { + this.currentAsyncValidator = keys[index + 1]; + var validator = this.asyncValidators[this.currentAsyncValidator]; + validator.rules[validator.rule].asyncRule(validator.value, validator.params, this, completion); + } + } + }, { + key: "fail", + value: function fail(completion) { + var validator = this.asyncValidators[this.currentAsyncValidator]; + this.failedAsyncValidator = this.currentAsyncValidator; + completion.fail(); + } }, { key: "fieldValid", value: function fieldValid(field) { @@ -524,19 +559,19 @@ function () { rule = _this$helpers$normali2[1], params = _this$helpers$normali2[2]; - if (!this.helpers.passes(rule, value, params, rules)) { - this.fields[field] = false; - var message = this.helpers.message(rule, field, options, rules); - - if (params.length > 0 && rules[rule].hasOwnProperty('messageReplace')) { - message = rules[rule].messageReplace(message, params); - } - - this.errorMessages[field] = message; + if (this.helpers.isAsync(rule, rules)) { + this.asyncValidators["".concat(field, ":").concat(rule)] = { + value: value, + rule: rule, + params: params, + field: field, + options: options, + rules: rules + }; + } - if (this.messagesShown || this.visibleFields.includes(field)) { - return this.helpers.element(message, options); - } + if (!this.helpers.passes(rule, value, params, rules) || this.helpers.isAsync(rule, rules) && this.failedAsyncValidator == "".concat(field, ":").concat(rule)) { + return this.fieldFailure(field, rule, rules, options, params); } } } catch (err) { @@ -554,6 +589,22 @@ function () { } } } + }, { + key: "fieldFailure", + value: function fieldFailure(field, rule, rules, options, params) { + this.fields[field] = false; + var message = this.helpers.message(rule, field, options, rules); + + if (params.length > 0 && rules[rule].hasOwnProperty('messageReplace')) { + message = rules[rule].messageReplace(message, params); + } + + this.errorMessages[field] = message; + + if (this.messagesShown) { + return this.helpers.element(message, options); + } + } }]); return SimpleReactValidator; diff --git a/dist/simple-react-validator.min.js b/dist/simple-react-validator.min.js index c589753..1956928 100644 --- a/dist/simple-react-validator.min.js +++ b/dist/simple-react-validator.min.js @@ -1,2 +1,2 @@ // Simple React Validator v1.2.0 | Created By Dockwa | MIT License | 2017 - Present -!function(e,t){"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?module.exports=t(require("react")):e.SimpleReactValidator=t(e.React)}(this,function(n){"use strict";function g(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=[],s=!0,n=!1,a=void 0;try{for(var i,u=e[Symbol.iterator]();!(s=(i=u.next()).done)&&(r.push(i.value),!t||r.length!==t);s=!0);}catch(e){n=!0,a=e}finally{try{s||null==u.return||u.return()}finally{if(n)throw a}}return r}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function b(t){for(var e=1;e=parseFloat(t[0])&&r.helpers.size(e,t[2])<=parseFloat(t[1])},messageReplace:function(e,t){return e.replace(":min",t[0]).replace(":max",t[1]).replace(":type",r.helpers.sizeText(t[2]))}},boolean:{message:"The :attribute must be a boolean.",rule:function(e){return!1===e||!0===e}},card_exp:{message:"The :attribute must be a valid expiration date.",rule:function(e){return r.helpers.testRegex(e,/^(([0]?[1-9]{1})|([1]{1}[0-2]{1}))\s?\/\s?(\d{2}|\d{4})$/)}},card_num:{message:"The :attribute must be a valid credit card number.",rule:function(e){return r.helpers.testRegex(e,/^\d{4}\s?\d{4,6}\s?\d{4,5}\s?\d{0,8}$/)}},currency:{message:"The :attribute must be a valid currency.",rule:function(e){return r.helpers.testRegex(e,/^\$?(\d{1,3})(\,?\d{3})*\.?\d{0,2}$/)}},date:{message:"The :attribute must be a date.",rule:function(e){return r.helpers.momentInstalled()&&moment.isMoment(e)}},date_equals:{message:"The :attribute must be on :date.",rule:function(e,t){return r.helpers.momentInstalled()&&moment.isMoment(e)&&e.isSame(t[0],"day")},messageReplace:function(e,t){return e.replace(":date",t[0].format("MM/DD/YYYY"))}},email:{message:"The :attribute must be a valid email address.",rule:function(e){return r.helpers.testRegex(e,/^[A-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i)}},in:{message:"The selected :attribute must be :values.",rule:function(e,t){return-1=parseFloat(t[0])},messageReplace:function(e,t){return e.replace(":min",t[0]).replace(":type",r.helpers.sizeText(t[1]))}},not_in:{message:"The selected :attribute must not be :values.",rule:function(e,t){return-1===t.indexOf(e)},messageReplace:function(e,t){return e.replace(":values",r.helpers.toSentence(t))}},not_regex:{message:"The :attribute must not match the required pattern.",rule:function(e,t){return!r.helpers.testRegex(e,"string"==typeof t[0]||t[0]instanceof String?new RegExp(t[0]):t[0])}},numeric:{message:"The :attribute must be a number.",rule:function(e){return r.helpers.numeric(e)}},phone:{message:"The :attribute must be a valid phone number.",rule:function(e){return r.helpers.testRegex(e,/^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$/)}},regex:{message:"The :attribute must match the required pattern.",rule:function(e,t){return r.helpers.testRegex(e,"string"==typeof t[0]||t[0]instanceof String?new RegExp(t[0]):t[0])}},required:{message:"The :attribute field is required.",rule:function(e){return!r.helpers.isBlank(e)},required:!0},size:{message:"The :attribute must be :size:type.",rule:function(e,t){return r.helpers.size(e,t[1])==parseFloat(t[0])},messageReplace:function(e,t){return e.replace(":size",t[0]).replace(":type",r.helpers.sizeText(t[1]))}},string:{message:"The :attribute must be a string.",rule:function(e){return a(e)===a("string")}},typeof:{message:"The :attribute is not the correct type of :type.",rule:function(e,t){return a(e)===a(t[0])},messageReplace:function(e,t){return e.replace(":type",a(t[0]))}},url:{message:"The :attribute must be a url.",rule:function(e){return r.helpers.testRegex(e,/^(https?|ftp):\/\/(-\.)?([^\s/?\.#-]+\.?)+(\/[^\s]*)?$/i)}}},e.validators||{}),s.locales.hasOwnProperty(e.locale)||console.warn("Locale not found! Make sure it is spelled correctly and the locale file is loaded.");var t=s.locales[e.locale]||{};Object.keys(this.rules).forEach(function(e){r.rules[e].message=t[e]||r.rules[e].message}),this.messages=e.messages||{},this.className=e.className,this.autoForceUpdate=e.autoForceUpdate||!1,!1===e.element?this.element=function(e){return e}:e.hasOwnProperty("element")?this.element=e.element:"object"===("undefined"==typeof navigator?"undefined":a(navigator))&&"ReactNative"===navigator.product?this.element=function(e){return e}:this.element=function(e,t){return n.createElement("div",{className:t||r.className||"srv-validation-message"},e)}}return e(s,null,[{key:"addLocale",value:function(e,t){this.locales[e]=t}}]),e(s,[{key:"getErrorMessages",value:function(){return this.errorMessages}},{key:"showMessages",value:function(){this.messagesShown=!0,this.helpers.forceUpdateIfNeeded()}},{key:"hideMessages",value:function(){this.messagesShown=!1,this.helpers.forceUpdateIfNeeded()}},{key:"allValid",value:function(){for(var e in this.fields)if(!1===this.fieldValid(e))return!1;return!0}},{key:"fieldValid",value:function(e){return this.fields.hasOwnProperty(e)&&!0===this.fields[e]}},{key:"purgeFields",value:function(){this.fields={},this.errorMessages={}}},{key:"messageWhenPresent",value:function(e){var t=1=parseFloat(t[0])&&r.helpers.size(e,t[2])<=parseFloat(t[1])},messageReplace:function(e,t){return e.replace(":min",t[0]).replace(":max",t[1]).replace(":type",r.helpers.sizeText(t[2]))}},boolean:{message:"The :attribute must be a boolean.",rule:function(e){return!1===e||!0===e}},card_exp:{message:"The :attribute must be a valid expiration date.",rule:function(e){return r.helpers.testRegex(e,/^(([0]?[1-9]{1})|([1]{1}[0-2]{1}))\s?\/\s?(\d{2}|\d{4})$/)}},card_num:{message:"The :attribute must be a valid credit card number.",rule:function(e){return r.helpers.testRegex(e,/^\d{4}\s?\d{4,6}\s?\d{4,5}\s?\d{0,8}$/)}},currency:{message:"The :attribute must be a valid currency.",rule:function(e){return r.helpers.testRegex(e,/^\$?(\d{1,3})(\,?\d{3})*\.?\d{0,2}$/)}},date:{message:"The :attribute must be a date.",rule:function(e){return r.helpers.momentInstalled()&&moment.isMoment(e)}},date_equals:{message:"The :attribute must be on :date.",rule:function(e,t){return r.helpers.momentInstalled()&&moment.isMoment(e)&&e.isSame(t[0],"day")},messageReplace:function(e,t){return e.replace(":date",t[0].format("MM/DD/YYYY"))}},email:{message:"The :attribute must be a valid email address.",rule:function(e){return r.helpers.testRegex(e,/^[A-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i)}},in:{message:"The selected :attribute must be :values.",rule:function(e,t){return-1=parseFloat(t[0])},messageReplace:function(e,t){return e.replace(":min",t[0]).replace(":type",r.helpers.sizeText(t[1]))}},not_in:{message:"The selected :attribute must not be :values.",rule:function(e,t){return-1===t.indexOf(e)},messageReplace:function(e,t){return e.replace(":values",r.helpers.toSentence(t))}},not_regex:{message:"The :attribute must not match the required pattern.",rule:function(e,t){return!r.helpers.testRegex(e,"string"==typeof t[0]||t[0]instanceof String?new RegExp(t[0]):t[0])}},numeric:{message:"The :attribute must be a number.",rule:function(e){return r.helpers.numeric(e)}},phone:{message:"The :attribute must be a valid phone number.",rule:function(e){return r.helpers.testRegex(e,/^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$/)}},regex:{message:"The :attribute must match the required pattern.",rule:function(e,t){return r.helpers.testRegex(e,"string"==typeof t[0]||t[0]instanceof String?new RegExp(t[0]):t[0])}},required:{message:"The :attribute field is required.",rule:function(e){return!r.helpers.isBlank(e)},required:!0},size:{message:"The :attribute must be :size:type.",rule:function(e,t){return r.helpers.size(e,t[1])==parseFloat(t[0])},messageReplace:function(e,t){return e.replace(":size",t[0]).replace(":type",r.helpers.sizeText(t[1]))}},string:{message:"The :attribute must be a string.",rule:function(e){return a(e)===a("string")}},typeof:{message:"The :attribute is not the correct type of :type.",rule:function(e,t){return a(e)===a(t[0])},messageReplace:function(e,t){return e.replace(":type",a(t[0]))}},url:{message:"The :attribute must be a url.",rule:function(e){return r.helpers.testRegex(e,/^(https?|ftp):\/\/(-\.)?([^\s/?\.#-]+\.?)+(\/[^\s]*)?$/i)}}},e.validators||{}),s.locales.hasOwnProperty(e.locale)||console.warn("Locale not found! Make sure it is spelled correctly and the locale file is loaded.");var t=s.locales[e.locale]||{};Object.keys(this.rules).forEach(function(e){r.rules[e].message=t[e]||r.rules[e].message}),this.messages=e.messages||{},this.className=e.className,this.autoForceUpdate=e.autoForceUpdate||!1,!1===e.element?this.element=function(e){return e}:e.hasOwnProperty("element")?this.element=e.element:"object"===("undefined"==typeof navigator?"undefined":a(navigator))&&"ReactNative"===navigator.product?this.element=function(e){return e}:this.element=function(e,t){return n.createElement("div",{className:t||r.className||"srv-validation-message"},e)}}return e(s,null,[{key:"addLocale",value:function(e,t){this.locales[e]=t}}]),e(s,[{key:"getErrorMessages",value:function(){return this.errorMessages}},{key:"showMessages",value:function(){this.messagesShown=!0,this.helpers.forceUpdateIfNeeded()}},{key:"hideMessages",value:function(){this.messagesShown=!1,this.helpers.forceUpdateIfNeeded()}},{key:"allValid",value:function(){for(var e in this.fields)if(!1===this.fieldValid(e))return!1;return!0}},{key:"asyncValid",value:function(e){if(this.failedAsyncValidator=null,!this.allValid())return e.fail();if(0===Object.keys(this.asyncValidators).length)return e.pass();this.currentAsyncValidator=Object.keys(this.asyncValidators)[0];var t=this.asyncValidators[this.currentAsyncValidator];t.rules[t.rule].asyncRule(t.value,t.params,this,e)}},{key:"pass",value:function(e){var t=Object.keys(this.asyncValidators),r=t.indexOf(this.currentAsyncValidator);if(r>=t.length-1)return e.pass();this.currentAsyncValidator=t[r+1];var s=this.asyncValidators[this.currentAsyncValidator];s.rules[s.rule].asyncRule(s.value,s.params,this,e)}},{key:"fail",value:function(e){this.asyncValidators[this.currentAsyncValidator];this.failedAsyncValidator=this.currentAsyncValidator,e.fail()}},{key:"fieldValid",value:function(e){return this.fields.hasOwnProperty(e)&&!0===this.fields[e]}},{key:"purgeFields",value:function(){this.fields={},this.errorMessages={}}},{key:"messageWhenPresent",value:function(e){var t=1 +