Form.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { useState } from 'react';
  2. import { IValidation } from '../components/textField/Types';
  3. import { checkIsEmpty, 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. console.log('init validation', initValidation);
  46. // validation detail about form item
  47. const [validation, setValidation] = useState(initValidation);
  48. // overall validation result to control following actions
  49. const [disabled, setDisabled] = useState<boolean>(true);
  50. const checkIsValid = (param: ICheckValidParam): IValidationItem => {
  51. const { value, key, rules } = param;
  52. let validDetail = {
  53. result: false,
  54. errText: '',
  55. };
  56. for (let i = 0; i < rules.length; i++) {
  57. const rule = rules[i];
  58. const checkResult = getCheckResult({
  59. value,
  60. extraParam: rule.extraParam,
  61. rule: rule.rule,
  62. });
  63. if (!checkResult) {
  64. validDetail = {
  65. result: true,
  66. errText: rule.errorText || '',
  67. };
  68. break;
  69. }
  70. }
  71. const validInfo = {
  72. ...validation,
  73. [key]: validDetail,
  74. };
  75. const isOverallValid = Object.values(validInfo).every(
  76. v => !(v as IValidationItem).result
  77. );
  78. setDisabled(!isOverallValid);
  79. setValidation(validInfo);
  80. return validDetail;
  81. };
  82. const checkFormValid = (form: IForm[]): boolean => {
  83. const requireCheckItems = form.filter(f => f.needCheck);
  84. if (requireCheckItems.some(item => !checkIsEmpty(item.value))) {
  85. return false;
  86. }
  87. const validations = Object.values(validation);
  88. return validations.every(v => !(v as IValidationItem).result);
  89. };
  90. const resetValidation = (form: IForm[]) => {
  91. const validation = form
  92. .filter(f => f.needCheck)
  93. .reduce(
  94. (acc, cur) => ({
  95. ...acc,
  96. [cur.key]: { result: cur.value === '', errText: '' },
  97. }),
  98. {}
  99. );
  100. setValidation(validation);
  101. };
  102. return {
  103. checkFormValid,
  104. checkIsValid,
  105. validation,
  106. disabled,
  107. setDisabled,
  108. resetValidation,
  109. };
  110. };