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;
|