diff --git a/dev/full/schema.js b/dev/full/schema.js index d82b1e99..6cb35635 100644 --- a/dev/full/schema.js +++ b/dev/full/schema.js @@ -74,7 +74,10 @@ module.exports = { required: true, hint: "Minimum 6 characters", styleClasses: "half-width", - validator: validators.string + validator: validators.string.locale({ + fieldIsRequired: "The password is required!", + textTooSmall: "Password must be at least {1} characters!" + }) }, { type: "input", inputType: "date", diff --git a/src/utils/validators.js b/src/utils/validators.js index c44bebac..9a9b219c 100644 --- a/src/utils/validators.js +++ b/src/utils/validators.js @@ -1,24 +1,6 @@ -import { isNil, isNumber, isString, isArray } from "lodash"; +import { defaults, isNil, isNumber, isString, isArray, isFunction } from "lodash"; import fecha from "fecha"; -function checkEmpty(value, required) { - if (isNil(value) || value === "") { - if (required) - return [msg(resources.fieldIsRequired)]; - else - return []; - } - return null; -} - -function msg(text) { - if (text != null && arguments.length > 1) - for (let i = 1; i < arguments.length; i++) - text = text.replace(/\{\d+?\}/, arguments[i]); - - return text; -} - let resources = { fieldIsRequired: "This field is required!", invalidFormat: "Invalid format!", @@ -50,135 +32,154 @@ let resources = { invalidTextContainSpec: "Invalid text! Cannot contains special characters" }; + +function checkEmpty(value, required, messages = resources) { + if (isNil(value) || value === "") { + if (required) + return [msg(messages.fieldIsRequired)]; + else + return []; + } + return null; +} + +function msg(text) { + if (text != null && arguments.length > 1) + for (let i = 1; i < arguments.length; i++) + text = text.replace("{" + (i - 1) + "}", arguments[i]); + + return text; +} + module.exports = { resources, - required(value, field) { - return checkEmpty(value, field.required); + required(value, field, model, messages = resources) { + return checkEmpty(value, field.required, messages); }, - number(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + number(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; let err = []; if (isNumber(value)) { if (!isNil(field.min) && value < field.min) - err.push(msg(resources.numberTooSmall, field.min)); + err.push(msg(messages.numberTooSmall, field.min)); if (!isNil(field.max) && value > field.max) - err.push(msg(resources.numberTooBig, field.max)); + err.push(msg(messages.numberTooBig, field.max)); } else - err.push(msg(resources.invalidNumber)); + err.push(msg(messages.invalidNumber)); return err; }, - integer(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + integer(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; if (!(Number(value) === value && value % 1 === 0)) - return [msg(resources.invalidNumber)]; + return [msg(messages.invalidNumber)]; }, - double(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + double(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; if (!isNumber(value) || isNaN(value)) - return [msg(resources.invalidNumber)]; + return [msg(messages.invalidNumber)]; }, - string(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + string(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; let err = []; if (isString(value)) { if (!isNil(field.min) && value.length < field.min) - err.push(msg(resources.textTooSmall, value.length, field.min)); + err.push(msg(messages.textTooSmall, value.length, field.min)); if (!isNil(field.max) && value.length > field.max) - err.push(msg(resources.textTooBig, value.length, field.max)); + err.push(msg(messages.textTooBig, value.length, field.max)); } else - err.push(msg(resources.thisNotText)); + err.push(msg(messages.thisNotText)); return err; }, - array(value, field) { + array(value, field, model, messages = resources) { if (field.required) { if (!isArray(value)) - return [msg(resources.thisNotArray)]; + return [msg(messages.thisNotArray)]; if (value.length == 0) - return [msg(resources.fieldIsRequired)]; + return [msg(messages.fieldIsRequired)]; } if (!isNil(value)) { if (!isNil(field.min)) if (value.length < field.min) - return [msg(resources.selectMinItems, field.min)]; + return [msg(messages.selectMinItems, field.min)]; if (!isNil(field.max)) if (value.length > field.max) - return [msg(resources.selectMaxItems, field.max)]; + return [msg(messages.selectMaxItems, field.max)]; } }, - date(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + date(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; let m = new Date(value); if (!m) - return [msg(resources.invalidDate)]; + return [msg(messages.invalidDate)]; let err = []; if (!isNil(field.min)) { let min = new Date(field.min); if (m.valueOf() < min.valueOf()) - err.push(msg(resources.dateIsEarly, fecha.format(m), fecha.format(min))); + err.push(msg(messages.dateIsEarly, fecha.format(m), fecha.format(min))); } if (!isNil(field.max)) { let max = new Date(field.max); if (m.valueOf() > max.valueOf()) - err.push(msg(resources.dateIsLate, fecha.format(m), fecha.format(max))); + err.push(msg(messages.dateIsLate, fecha.format(m), fecha.format(max))); } return err; }, - regexp(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + regexp(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; if (!isNil(field.pattern)) { let re = new RegExp(field.pattern); if (!re.test(value)) - return [msg(resources.invalidFormat)]; + return [msg(messages.invalidFormat)]; } }, - email(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + email(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (!re.test(value)) - return [msg(resources.invalidEmail)]; + return [msg(messages.invalidEmail)]; }, - url(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + url(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; let re = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g; if (!re.test(value)) - return [msg(resources.invalidURL)]; + return [msg(messages.invalidURL)]; }, - creditCard(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + creditCard(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; /* From validator.js code https://github.com/chriso/validator.js/blob/master/src/lib/isCreditCard.js @@ -186,7 +187,7 @@ module.exports = { const creditCard = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/; const sanitized = value.replace(/[^0-9]+/g, ""); if (!creditCard.test(sanitized)) { - return [msg(resources.invalidCard)]; + return [msg(messages.invalidCard)]; } let sum = 0; let digit; @@ -209,22 +210,29 @@ module.exports = { } if (!((sum % 10) === 0 ? sanitized : false)) - return [msg(resources.invalidCardNumber)]; + return [msg(messages.invalidCardNumber)]; }, - alpha(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + alpha(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; let re = /^[a-zA-Z]*$/; if (!re.test(value)) - return [msg(resources.invalidTextContainNumber)]; + return [msg(messages.invalidTextContainNumber)]; }, - alphaNumeric(value, field) { - let res = checkEmpty(value, field.required); if (res != null) return res; + alphaNumeric(value, field, model, messages = resources) { + let res = checkEmpty(value, field.required, messages); if (res != null) return res; let re = /^[a-zA-Z0-9]*$/; if (!re.test(value)) - return [msg(resources.invalidTextContainSpec)]; + return [msg(messages.invalidTextContainSpec)]; } }; + +Object.keys(module.exports).forEach(name => { + const fn = module.exports[name]; + if (isFunction(fn)) { + fn.locale = customMessages => (value, field, model) => fn(value, field, model, defaults(customMessages, resources)); + } +}); \ No newline at end of file diff --git a/test/unit/specs/utils/validators.spec.js b/test/unit/specs/utils/validators.spec.js index f32d78ff..14dc1cb0 100644 --- a/test/unit/specs/utils/validators.spec.js +++ b/test/unit/specs/utils/validators.spec.js @@ -420,11 +420,34 @@ describe("Validators", () => { it("should give the localized error message", () => { v.resources.fieldIsRequired = "A mezőt kötelező kitölteni!"; - v.resources.textTooSmall = "A szöveg túl rövid. {1} helyett {0}"; + v.resources.textTooSmall = "A szöveg túl rövid. Minimum {1} a {0} helyett"; expect(v.number(null, field)[0]).to.be.equal("A mezőt kötelező kitölteni!"); - expect(v.string("Ab", field)[0]).to.be.equal("A szöveg túl rövid. 2 helyett 5"); + expect(v.string("Ab", field)[0]).to.be.equal("A szöveg túl rövid. Minimum 5 a 2 helyett"); }); }); + + describe("test local custom error messages", () => { + + let field = { + min: 5, + max: 10, + required: true + }; + + let locNumber = v.number.locale({ + fieldIsRequired: "Ezt a mezőt kötelező kitölteni!", + numberTooSmall: "Ez a szám nem lehet kisebb mint {0}!" + }); + + it("should give the custom error message", () => { + expect(locNumber(null, field)[0]).to.be.equal("Ezt a mezőt kötelező kitölteni!"); + expect(locNumber(2, field)[0]).to.be.equal("Ez a szám nem lehet kisebb mint 5!"); + }); + + it("should give the default error message", () => { + expect(locNumber(30, field)[0]).to.be.equal("The number is too big! Maximum: 10"); + }); + }); }); \ No newline at end of file