UNPKG

@suyouwanggang/p-ui

Version:

`p-ui`是一套使用原生`Web Components`规范开发的跨框架UI组件库,基于`lit-elment`库开发。 [github项目地址](https://github.com/suyouwanggang/p-ui)

292 lines (266 loc) 9.16 kB
interface ValidateResult { valid: boolean; /**true ,验证通过,否则,验证不通过 */ type?: string; //错误类型 validationMessage?: string; //错误说明 } import NP from 'number-precision'; interface ValidateItem { method(input: unknown): ValidateResult | undefined; } const getTipLabel = function (input: HTMLInputElement) { let label = input.getAttribute('tipLabel'); if (label === null) { label = '此字段'; } return label; }; const requiredValidte: ValidateItem = { method(input: HTMLInputElement) { const value = input.value.trim(); const result: ValidateResult = { valid: true }; if (input.type === 'number') { const n = Number(value); if (isNaN(n)) { result.valid = false; result.type = 'typeMismatch'; result.validationMessage = '请填写有效的数字'; } } else { result.valid = value.length > 0; if (!result.valid) { result.type = 'valueMissing'; result.validationMessage = `请填写${getTipLabel(input)}`; } } return result; } }; const minValidte: ValidateItem = { method(input: HTMLInputElement) { if (input.value.length === 0) { return undefined; } const value = Number(input.value.trim()); const min = Number(input.getAttribute('min')); const result: ValidateResult = { valid: true } if (input.value !== '-' && isNaN(value)) { result.valid = false; result.type = 'typeMismatch'; result.validationMessage = '请填写有效的数字'; return result; } if (!isNaN(min)) { result.valid = value >= min; } if (!result.valid) { result.type = 'rangeUnderflow'; result.validationMessage = `值必须大于或等于${min}`; } return result; } }; const maxValidte: ValidateItem = { method(input: HTMLInputElement) { if (input.value.length === 0) { return undefined; } const value = Number(input.value.trim()); const max = Number(input.getAttribute('max')); const result: ValidateResult = { valid: true } if (input.value !== '-' && isNaN(value)) { result.valid = false; result.type = 'typeMismatch'; result.validationMessage = '请填写有效的数字'; return result; } if (!isNaN(max)) { result.valid = value <= max; result.type = 'rangOverflow'; } if (!result.valid) { result.type = 'rangeUnderflow'; result.validationMessage = `值必须小于或等于${max}`; } return result; } }; const getCountDecimals = function (n: Number) { if (Math.floor(n.valueOf()) === n) return 0; return n.toString().split('.')[1].length || 0; }; const stepValidte: ValidateItem = { method(input: HTMLInputElement) { if (input.value.length === 0) { return undefined; } const value = Number(input.value.trim()); const step = Number(input.getAttribute('step')); const result: ValidateResult = { valid: true } if (input.value !== '-' && isNaN(value)) { result.valid = false; result.type = 'typeMismatch'; result.validationMessage = '请填写数字'; return result; } let min = Number(input.getAttribute('min')); if (isNaN(min)) { min = 0; } const aValue = NP.minus( value ,min); const bValue = NP.divide(aValue,step); if (Math.floor(bValue)!==Math.ceil(bValue)) { result.valid = false; result.type = 'stepMismatch'; const closeMin = NP.plus(NP.times(Math.floor(bValue) , step) ,min) const closeMax = NP.plus(NP.times(Math.ceil(bValue) , step) ,min); result.validationMessage = `请输入有效值,两个最接近的数值分别是${closeMin}${closeMax}`; } return result; } }; const tooShortValidte: ValidateItem = { method(input: HTMLInputElement) { const value = input.value; const minlength = Number(input.getAttribute('minlength')); const result: ValidateResult = { valid: true }; if (!isNaN(minlength) && value.length < minlength) { result.valid = false; result.type = 'tooShort'; result.validationMessage = `请填写${minlength}个或者${minlength}个以上字符`; return result; } return result; } }; const tooLongValidte: ValidateItem = { method(input: HTMLInputElement) { const value = input.value; const maxlength = Number(input.getAttribute('maxlength')); const result: ValidateResult = { valid: true }; if (!isNaN(maxlength) && value.length > maxlength) { result.valid = false; result.type = 'tooLength'; result.validationMessage = `请填写${maxlength}个或者${maxlength}个以下字符`; return result; } return result; } }; const patternValidte: ValidateItem = { method(input: HTMLInputElement) { const value = input.value; const pattern = input.pattern; const result: ValidateResult = { valid: true }; if (pattern !== undefined) { const reg = new RegExp(pattern); result.valid = reg.test(value); if (!result.valid) { result.type = 'patternMismatch'; const message = input.getAttribute('patternErrorMessage'); result.validationMessage = message || `请与请求的格式:${pattern}一致`; } } return result; } } const customValidate: ValidateItem = { method(input: HTMLInputElement) { // tslint:disable-next-line: no-any const customValidateMethod = (input as any).customValidateMethod; const result: ValidateResult = { valid: true }; if (customValidateMethod) { const validateResult: ValidateResult = customValidateMethod.method(input); if (validateResult === null || validateResult === undefined) { return result; } if (!validateResult.valid) { result.valid = false; result.type = 'customError'; const message = input.getAttribute('customErrorMessage'); result.validationMessage = message || `自定义验证失败`; } } return result; } } const getDefaultValidateList = (inputEL: HTMLInputElement | unknown) => { const input = inputEL as any; const items: ValidateItem[] = []; if (input.required) { items.push(requiredValidte); } if (input.minLength) { items.push(tooShortValidte); } if (input.maxLength) { items.push(tooLongValidte); } if (input.type === 'number') { if (input.min !== undefined) { items.push(minValidte); } if (input.max !== undefined) { items.push(maxValidte); } if (input.step) { items.push(stepValidte); } } if (input.pattern !== undefined) { items.push(patternValidte); } if (input.customValidateMethod) { items.push(customValidate); } return items; } const getValidityResult: any = (input: HTMLInputElement | unknown) => { const items = getDefaultValidateList(input); const result: any = { badInput: false, customError: false, patternMismatch: false, rangeOverflow: false, rangeUnderflow: false, stepMismatch: false, tooLong: false, tooShort: false, typeMismatch: false, valid: true, valueMissing: false, message: [] }; for (let i = 0, j = items.length; i < j; i++) { const item = items[i]; const itemResult = item.method(input); if (itemResult !== undefined && !itemResult.valid) { result.valid = false; if (itemResult.type) { result[itemResult.type] = true; const mesage: any = { type: itemResult.type, message: itemResult.validationMessage }; result.message.push(mesage); } } } return Object.freeze(result); }; export { getValidityResult ,getCountDecimals };