Form.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { useState } from 'react';
  2. import { IValidation } from '../components/customInput/Types';
  3. import { checkEmptyValid, getCheckResult } from '../utils/Validation';
  4. export interface IForm {
  5. key: string;
  6. value?: any;
  7. needCheck?: boolean;
  8. }
  9. interface IValidationInfo {
  10. // check general validation
  11. checkFormValid: Function;
  12. // check detail validation
  13. checkIsValid: Function;
  14. validation: {
  15. [key: string]: IValidationItem;
  16. };
  17. disabled: boolean;
  18. setDisabled: Function;
  19. resetValidation: (form: IForm[]) => void;
  20. }
  21. export interface IValidationItem {
  22. result: boolean;
  23. errText: string;
  24. }
  25. export interface ICheckValidParam {
  26. value: string;
  27. key: string;
  28. // one input can contains multiple rules
  29. rules: IValidation[];
  30. }
  31. export const useFormValidation = (form: IForm[]): IValidationInfo => {
  32. const initValidation = form
  33. .filter(f => f.needCheck)
  34. .reduce(
  35. (acc, cur) => ({
  36. ...acc,
  37. [cur.key]: {
  38. result:
  39. typeof cur.value === 'string' ? cur.value === '' : cur.value === 0,
  40. errText: '',
  41. },
  42. }),
  43. {}
  44. );
  45. // validation detail about form item
  46. const [validation, setValidation] = useState(initValidation);
  47. // overall validation result to control following actions
  48. const isOverallValid = Object.values(validation).every(
  49. v => !(v as IValidationItem).result
  50. );
  51. const [disabled, setDisabled] = useState<boolean>(!isOverallValid);
  52. const checkIsValid = (param: ICheckValidParam): IValidationItem => {
  53. const { value, key, rules } = param;
  54. let validDetail = {
  55. result: false,
  56. errText: '',
  57. };
  58. for (let i = 0; i < rules.length; i++) {
  59. const rule = rules[i];
  60. const checkResult = getCheckResult({
  61. value,
  62. extraParam: rule.extraParam,
  63. rule: rule.rule,
  64. });
  65. if (!checkResult) {
  66. validDetail = {
  67. result: true,
  68. errText: rule.errorText || '',
  69. };
  70. break;
  71. }
  72. }
  73. const validInfo = {
  74. ...validation,
  75. [key]: validDetail,
  76. };
  77. const isOverallValid = Object.values(validInfo).every(
  78. v => !(v as IValidationItem).result
  79. );
  80. setDisabled(!isOverallValid);
  81. setValidation(validInfo);
  82. return validDetail;
  83. };
  84. const checkFormValid = (form: IForm[]): boolean => {
  85. const requireCheckItems = form.filter(f => f.needCheck);
  86. if (requireCheckItems.some(item => !checkEmptyValid(item.value))) {
  87. return false;
  88. }
  89. const validations = Object.values(validation);
  90. return validations.every(v => !(v as IValidationItem).result);
  91. };
  92. const resetValidation = (form: IForm[]) => {
  93. const validation = form
  94. .filter(f => f.needCheck)
  95. .reduce(
  96. (acc, cur) => ({
  97. ...acc,
  98. [cur.key]: { result: cur.value === '', errText: '' },
  99. }),
  100. {}
  101. );
  102. setValidation(validation);
  103. };
  104. return {
  105. checkFormValid,
  106. checkIsValid,
  107. validation,
  108. disabled,
  109. setDisabled,
  110. resetValidation,
  111. };
  112. };