import _ from "lodash"; import { numArr, strArr } from "./const"; export function formatAndMaskingProvider(key:string, target: EventTarget|any, formatStrArray:string[], actualValue:string) { const cursorIndex = target.selectionStart; const pattern = /^(?=.*[0-9a-zA-Z!@#$%^&*()_+{}\[\]:;<>,.?/~` -])[0-9a-zA-Z!@#$%^&*()_+{}\[\]:;<>,.?/~` -]{0,1}$/; if (pattern.test(key) || key === "Backspace") { const textValueArray = _.cloneDeep(actualValue.split("")); const { depencyObj } = prepareActualFormatAndFormatObj(formatStrArray); const getExtraIndex = (depencyObj, cursorIndex) => { let extraIndexCount = 0; Object.keys(depencyObj).map((e) => { if (cursorIndex >= e) { extraIndexCount = extraIndexCount + depencyObj[e].length; } }); return extraIndexCount; }; const actualIndex = cursorIndex - getExtraIndex(depencyObj, cursorIndex); const updatedTextArr = setValueAtIndex( key === "Backspace" ? actualIndex > 0 ? actualIndex - 1 : actualIndex : actualIndex >= 0 ? actualIndex : 0, key === "Backspace" ? undefined : key, textValueArray ); const { updatedMaskedValue, isValidInput } = prepareMaskingAndFormating( updatedTextArr, formatStrArray ); const updatedActualStr = updatedTextArr.join(""); return { isValidInput, updatedMaskedValue, updatedActualStr }; } } export function prepareMaskingAndFormating( textArray: string[], formatStrArray: string[] ) { const formattedValue = []; const { formatObj, actualFormat } = prepareActualFormatAndFormatObj(formatStrArray); let isValidInput = actualFormat.length < textArray.length ? false : true; textArray.map((elem, i) => { if (!isValidInput) { return; } if (formatObj[i]) { formattedValue.push(false); } switch (actualFormat[i]) { case "0": formattedValue.push(elem); break; case "9": isValidInput = numArr.includes(elem); formattedValue.push(elem); break; case "A": isValidInput = strArr.includes(elem.toLowerCase()); formattedValue.push(elem); break; case "XA": isValidInput = strArr.includes(elem.toLowerCase()); formattedValue.push("X"); break; case "X9": isValidInput = numArr.includes(elem); formattedValue.push("X"); break; case "X0": formattedValue.push("X"); break; case "X": formattedValue.push("X"); break; } }); const availableFormat = Object.keys(formatObj); availableFormat.map((e, i) => { if (formattedValue[`${+e + i}`] === false) formattedValue[`${+e + i}`] = formatObj[e]; }); return { updatedMaskedValue: formattedValue.join(""), isValidInput: isValidInput, }; } function setValueAtIndex(index, value, array) { if (index >= 0 && index < array.length) { const newArray = value === undefined ? [...array.slice(0, index), ...array.slice(index + 1)] : [...array.slice(0, index), value, ...array.slice(index)]; return newArray; } else if (index === array.length && value !== undefined) { const newArray = [...array, value]; return newArray; } else { return array; } } function prepareActualFormatAndFormatObj(formatStrArray: string[]) { const formatObj = {}; const depencyObj = {}; const actualFormat = formatStrArray.filter((e, i) => { if ( e === "0" || e === "9" || e === "A" || e === "X" || e === "XA" || e === "X0" || e === "X9" ) { return true; } else { let countAdded = i; formatObj[i - Object.keys(formatObj).length || 0] = e; Object.keys(formatObj).map((e) => { countAdded = countAdded + formatObj[e].length; }); depencyObj[countAdded] = e; return false; } }); return { formatObj, actualFormat, depencyObj }; }