forked from assisrafael/react-bootstrap-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuseFormControl.js
111 lines (88 loc) · 2.32 KB
/
useFormControl.js
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
108
109
110
111
import { useContext, useCallback } from 'react';
import { isEmptyStringLike, isBoolean, isFunction } from 'js-var-type';
import { FormContext } from './form-helpers';
import { toDatetimeLocal, fromDatetimeLocal } from '../../utils/formatters';
export function useFormControl(name, type, hooks) {
const formState = useContext(FormContext);
const { afterChange } = hooks;
function setValue(value) {
formState.update(name, value);
if (isFunction(afterChange)) {
afterChange(value);
}
}
const register = useCallback(
(ref) => {
formState.register(name, ref);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[name]
);
return {
getValue: () => encode(formState.getValue(name), type),
setValue,
handleOnChange: ({ target }, _type) => {
const value = getTargetValue(target);
const decodedValue = decode(value, type || _type);
setValue(decodedValue);
},
register,
getFormData: () => formState.getFormData(),
isValid: () => formState.getValidationMessage(name) === '',
getFormSubmitedAttempted: () => formState.getSubmitedAttempted(),
};
}
function getEmptyValue(type) {
switch (type) {
case 'boolean':
return false;
case 'array':
return [];
default:
return '';
}
}
function encode(value, type) {
if (isEmptyStringLike(value)) {
return getEmptyValue(type);
}
if (type === 'datetime-local') {
return toDatetimeLocal(value);
}
if (type === 'number' && isNaN(value)) {
return;
}
return value;
}
function decode(value, type) {
if (type === 'number') {
return parseFloat(value);
}
if (type === 'boolean') {
return isBoolean(value) ? value : value === 'true';
}
return value;
}
function getTargetValue(target) {
let value = target.type === 'checkbox' ? target.checked : target.value;
if (target.type === 'number') {
value = target.valueAsNumber;
if (isNaN(value)) {
value = undefined;
}
}
if (target.type === 'datetime-local') {
value = fromDatetimeLocal(target.value);
}
if (target.type === 'select-one') {
if (value && ['{', '['].includes(value[0])) {
try {
value = JSON.parse(value);
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
}
}
return value;
}