UNPKG

@amxchange/grid-view-web-client

Version:

amxchange grid view framework web client in react ( a module extracted from existing jax )

347 lines (338 loc) 13.5 kB
import React from "react"; import moment from "moment"; // import { I18n } from "@shared/modules/utils/LangUtil"; const I18n = key => key; export const ERROR_MSGS = { DEFAULT: "g.msg.defaulterror", FIELD_EMPTY: "g.msg.emptyfield", PWD_INVALID: "g.msg.pwdinvalid", FAILED: "g.msg.faild", INVALID_EMAIL: "g.msg.invalidemail", INVALID_CIVILID: "g.msg.invalidcivilid2", SP_CH_NOT_ALLOWED: "g.msg.spchnotallowed", NO_SPACES: "g.msg.nospace", THESE_SP_CH_NOT_ALLOWED: "g.msg.thesespchnotallowed", NO_NUMBERS: "g.msg.numbernotallowed", ONLY_ALPHABETS: "g.msg.onlylaphabet", INVALID_INPUT: "g.msg.invalidinput", ONLY_NUMBERS: "g.msg.onlynumbers", ONLY_ARABIC: "g.msg.onlyarabic", ONLY_ALPHANUMERIC: "g.msg.onlynumberallowed", THIS_FIELD: "g.lbl.thisfield", INVALID_DATE: "g.msg.invaliddate" }; export const defaultConfig = { label: I18n(ERROR_MSGS.THIS_FIELD), hiddenLabel: I18n(ERROR_MSGS.THIS_FIELD) }; export const commonValidationProfiles = { default(val, config) { config = config || defaultConfig; config.label = config.label || config.hiddenLabel; if (config.type === "date") { if (val === "Invalid date") { val = ""; } // console.log({ val: val }); if (val) { let _val = typeof val === "number" ? moment(val) : val; // additional check to handle timestamp in "val". This will convert ts into moment object first. let _isValid = moment(_val, "DD/MM/YYYY", true).isValid(); // console.log({_isValid: _isValid}) if (_isValid && config.additionalValidations && config.additionalValidations.isValidDate) { _isValid = config.additionalValidations.isValidDate(_val); } if (!_isValid) { return { valid: false, errorMsg: I18n(ERROR_MSGS.INVALID_DATE) }; } }else { return { valid: false, errorMsg: "Please Enter a Valid Date" }; } } if (config.type === "daterange") { if (Array.isArray(val) && val.some(v => !v || v === "Invalid date")) { val = ""; } if (Array.isArray(val)) { let _val = val.map(el => { let _val = typeof el === "number" ? moment(el) : el; // additional check to handle timestamp in "val". This will convert ts into moment object first. let format = config.additionalValidations && config.additionalValidations.format ? config.additionalValidations.format : "DD/MM/YYYY"; let isValid = moment(_val, format, true).isValid(); return isValid; }); let _isInValid = _val.some(el => el === "Invalid date" || el === false); if (!_isInValid && config.additionalValidations && config.additionalValidations.isValidDate) { _isInValid = !config.additionalValidations.isValidDate(val[0]); // currently applying validation only on start date of a date range } if (_isInValid) { return { valid: false, errorMsg: I18n(ERROR_MSGS.INVALID_DATE) }; } } } if (config.type === "currency") { val = (val || {}).value; } if (val === "" || val === null || val === undefined) { let emptyErr = config.emptyErr || `Please enter ${config.label || config.hiddenLabel || I18n(ERROR_MSGS.THIS_FIELD)}`; return { valid: false, errorMsg: emptyErr }; } else if (config.sizeRange) { let min = config.sizeRange[0] || 0; let max = config.sizeRange[1] || Infinity; if ((config.type === "number" || config.type === "currency") && typeof val === "number") { val = String(val).split(".")[0]; } if (val.length <= max && val.length >= min) { return { valid: true }; } else { let errorMsg = ""; let numOrChar = config.type === "number" ? "digits" : "characters"; if (min < 0 && max > 0) { errorMsg = I18n(`g.msg.maxlenerr:${config.label}:${max}:${numOrChar}`); } else if (max < 0 && min > 0) { errorMsg = I18n(`g.msg.minlenerr:${config.label}:${min}:${numOrChar}`); } else if (min >= 0 && max >= 0) { if (min === max) { errorMsg = I18n(`g.msg.exlenerr:${config.label}:${min}:${numOrChar}`); } else { errorMsg = I18n(`g.msg.minmaxlenerr:${config.label}:${min}:${max}:${numOrChar}`); } } else { errorMsg = I18n(ERROR_MSGS.INVALID_INPUT); } return { valid: false, errorMsg }; } } else if (config.allowedSizes) { let allowedSizes = config.allowedSizes || []; if (allowedSizes.length === 0) return { valid: true }; if (allowedSizes.indexOf(val.length.toString()) === -1) { let errorMsg = I18n(ERROR_MSGS.INVALID_INPUT); if (allowedSizes.length === 1) { errorMsg = I18n(`g.msg.moblenerr:${allowedSizes[0]}`); } else { errorMsg = I18n(`g.msg.moblenerr1:${allowedSizes.join(", ")}`); } return { valid: false, errorMsg }; } else { return { valid: true }; } } else { return { valid: true }; } }, noSpaces(val) { let containsSpace = /\s/g.test(val); return { valid: !containsSpace, errorMsg: I18n(ERROR_MSGS.NO_SPACES) }; }, noNumbers(val) { let hasNumber = /\d/.test(val); return { valid: !hasNumber, errorMsg: I18n(ERROR_MSGS.NO_NUMBERS) }; }, theseSpChNotAllowed(val) { let containsUnwantedSpChars = /[#^&*()_+\-=\[\]{};':"\\|,.<>\/?`~]/.test(val); return { valid: !containsUnwantedSpChars, errorMsg: I18n(ERROR_MSGS.THESE_SP_CH_NOT_ALLOWED) }; }, sentenceCase(val) { let words = val.split(" "); let sentenceCasified = words .map(word => { return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); }) .join(" "); return { valid: words === sentenceCasified, corrected: sentenceCasified, errorMsg: I18n(ERROR_MSGS.INVALID_INPUT) }; }, password(val) { let containsDigits = /[0-9]/.test(val); let containsUpper = /[A-Z]/.test(val); let containsLower = /[a-z]/.test(val); let containsSpecialChars = /[!@%$]/.test(val); let containsUnwantedSpChars = /[#^&*()_+\-=\[\]{};':"\\|,.<>\/?`~]/.test(val); if (containsDigits && containsUpper && containsLower && containsSpecialChars && !containsUnwantedSpChars) { return { valid: true }; } else { return { valid: false, errorMsg: I18n(ERROR_MSGS.PWD_INVALID) }; } }, email(val) { let valid = /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/.test( val ); return { valid, errorMsg: I18n(ERROR_MSGS.INVALID_EMAIL) }; }, civilid(val) { let valid = !isNaN(val) && val.toString().indexOf(".") === -1; return { valid, errorMsg: I18n(ERROR_MSGS.INVALID_CIVILID) }; }, spCharacterNotAllowed(val) { let notAllowed = /[ `~!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(val); return { valid: !notAllowed, errorMsg: I18n(ERROR_MSGS.SP_CH_NOT_ALLOWED) }; }, spCharsAndArabic(val) { // let arabicAndSplChars = /[\u0600-\u06FF\s]+/; // let englishChars = /[a-zA-Z\d]/ // let unwantedSpChars = /[^!%@&#*()\-_.\/\\,:;\u0600-\u06FF]+/; return { valid: /^[\d\s\u0621-\u064A!%@&#*()\-_.\/\\,:;]+$/.test(val), errorMsg: "Invalid Input" }; }, onlyAlphabets(val) { let valid = /[a-z ,.'-]+/.test(val); return { valid: valid, errorMsg: I18n(ERROR_MSGS.ONLY_ALPHABETS) }; }, onlyNumbers(val) { let customIsNaN = value => (/[\s.]+/.test(value) ? true : isNaN(value)); // since native isNaN accepts " " (single space) and also "." (single period after a digit) and we do not want that in our case. return { valid: !isNaN(val), errorMsg: I18n(ERROR_MSGS.ONLY_NUMBERS) }; }, onlyArabicChars(val) { let valid = /[\u0621-\u064A\u0660-\u0669 ]+/.test(val); return { valid, errorMsg: I18n(ERROR_MSGS.ONLY_ARABIC) }; }, currencyInput(val) { val = String(val); let isPositive = val >= 0; let containsLeadingZeros = false; let newValue = val.replace(/^0+/, ""); if (val !== "0" && val.indexOf("0.") !== 0 && newValue !== val) { containsLeadingZeros = true; } let valid = isPositive && !containsLeadingZeros; return { valid, errorMsg: I18n(ERROR_MSGS.INVALID_INPUT) }; }, validName(val) { let valid = /^(?![0-9 ]*$)[a-zA-Z0-9 ]+$/.test(val); return { valid, errorMsg: I18n(ERROR_MSGS.INVALID_INPUT) }; }, validOTP(val) { let valid = !isNaN(val.substr(4)); return { valid, errorMsg: I18n(ERROR_MSGS.INVALID_INPUT) }; }, strictlyAlphanumeric(val) { let valid = /^(\d+[a-zA-Z]|[a-zA-Z]+\d)[a-zA-Z\d]*$/.test(val); return { valid, errorMsg: I18n(ERROR_MSGS.ONLY_ALPHANUMERIC) }; }, onlyPositiveIntegers(val) { //for numbers with no decimal/period and space let customIsNaN = value => (/[\s.]+/.test(value) ? true : isNaN(value)); // since native isNaN accepts " " (single space) and also "." (single period after a digit) and we do not want that in our case. return { valid: !customIsNaN(val), errorMsg: ERROR_MSGS.ONLY_NUMBERS }; } }; export const getValidators = validationProfileKeys => { let validators = (validationProfileKeys || []).map(v => { if (commonValidationProfiles[v] === undefined) { if (typeof v === "function") return v; if (v instanceof RegExp || validationService.validRegex(v)) { let regExp = v; if (validationService.validRegex(v)) regExp = validationService.regexpStringToObj(v); return value => ({ valid: regExp.test(value), errorMsg: "Invalid Input" }); } console.error(`no validation profile found for ${v}`); } return commonValidationProfiles[v]; }); return validators; }; export const REGEX_SPLITTER = "REGEX_SPLITTER"; export const validationService = { regexpStringToObj(regexpString) { let regexpMatcher = /\/(.+)\/([gmiyus]{0,6})/; let regexpWithoutSlashes = regexpString.replace(regexpMatcher, `$1${REGEX_SPLITTER}$2`); return new RegExp(...regexpWithoutSlashes.split(REGEX_SPLITTER)); }, validRegex(str) { let isValid = true; try { new RegExp(str); } catch (e) { isValid = false; } return isValid; }, validate(validators, { value, config }) { let results = []; for (let i = 0; i < validators.length; i++) { let validator = validators[i]; if (validator) results.push(validator(value, config)); } return results; } };