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;