summaryrefslogtreecommitdiff
path: root/src/core/utils/formValidation.js
diff options
context:
space:
mode:
authorRafi Zadanly <zadanlyr@gmail.com>2023-01-24 15:54:48 +0700
committerRafi Zadanly <zadanlyr@gmail.com>2023-01-24 15:54:48 +0700
commitee4297280c1305c7e03bedd4df63ccf136c28c6c (patch)
tree62eb00777f42542a37c63687dd1536f8f56df894 /src/core/utils/formValidation.js
parent23b31aa10302cc990f3fb083b8189233b2e9e08d (diff)
Merapihkan struktur folder
Diffstat (limited to 'src/core/utils/formValidation.js')
-rw-r--r--src/core/utils/formValidation.js107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/core/utils/formValidation.js b/src/core/utils/formValidation.js
new file mode 100644
index 00000000..0e83f4cc
--- /dev/null
+++ b/src/core/utils/formValidation.js
@@ -0,0 +1,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; \ No newline at end of file