@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
JavaScript
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;
}
};