summaryrefslogtreecommitdiff
path: root/src2/core/utils/formValidation.js
blob: 0e83f4cc681e750772491f70b7ce54b7aa4201e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { useCallback, useEffect, useState } from "react";

const validateForm = (data, queries, hasChangedInputs = null) => {
  let result = { valid: true, errors: {} };
  
  for (const query in queries) {
    if (!hasChangedInputs || (hasChangedInputs && hasChangedInputs[query])) {
      const value = data[query];
      const rules = queries[query];
      let errors = [];
      let label = null;
      for (const rule of rules) {
        let emailValidationRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        if (rule.startsWith('label:')) {
          label = rule.replace('label:', '');
        } else if (rule === 'required' && !value) {
          errors.push('tidak boleh kosong');
        } else if (rule === 'email' && !value.match(emailValidationRegex)) {
          errors.push('harus format johndoe@example.com');
        } else if (rule.startsWith('maxLength:')) {
          let maxLength = parseInt(rule.replace('maxLength:', ''));
          if (value && value.length > maxLength) errors.push(`maksimal ${maxLength} karakter`);
        }
      }
      if (errors.length > 0) {
        result.errors[query] = (label || query) + ' ' + errors.join(', ');
      }
    }
  }

  if (Object.keys(result.errors).length > 0) {
    result.valid = false;
  }

  return result;
}

const useFormValidation = ({ initialFormValue = {}, validationScheme = {} }) => {
  const [ formInputs, setFormInputs ] = useState(initialFormValue);
  const [ formErrors, setFormErrors ] = useState({});
  const [ formValidation ] = useState(validationScheme);
  const [ hasChangedInputs, setHasChangedInputs ] = useState({});
  
  const handleFormSubmit = (event, func) => {
    if (event) {
      event.preventDefault();
      
      // Make all input to be has changed mode to revalidate
      const changedInputs = {};
      for (const key in formInputs) changedInputs[key] = true;
      setHasChangedInputs(changedInputs);

      const { valid, errors } = validateForm(formInputs, formValidation, changedInputs);
      setFormErrors(errors);
      
      if (valid) func();
    }
  };

  const setChangedInput = (name, value = true) => {
    setHasChangedInputs((hasChangedInputs) => ({
      ...hasChangedInputs,
      [name]: value
    }));
  };
 
  const handleInputChange = (event) => {
    setFormInputs((formInputs) => ({
      ...formInputs,
      [event.target.name]: event.target.value
    }));
    setChangedInput(event.target.name);
  };

  const handleSelectChange = useCallback((name, value) => {
    setFormInputs((formInputs) => ({
      ...formInputs,
      [name]: value
    }));
    setChangedInput(name);
  }, []);

  const handleFormReset = () => {
    setFormInputs(initialFormValue);
    setFormErrors({});
    setHasChangedInputs({});
  }

  useEffect(() => {
    if (formInputs) {
      const { errors } = validateForm(formInputs, formValidation, hasChangedInputs);
      setFormErrors(errors);
    }
  }, [ formInputs, formValidation, hasChangedInputs ])
 
  return {
    handleFormReset,
    handleFormSubmit,
    handleInputChange,
    handleSelectChange,
    hasChangedInputs,
    formInputs,
    formErrors
  };
 };

export default useFormValidation;