Skip to content
This repository was archived by the owner on Apr 9, 2025. It is now read-only.

Commit 6493c80

Browse files
author
Daniel Requejo
committed
Compact _refs
1 parent 58d832d commit 6493c80

File tree

6 files changed

+70
-49
lines changed

6 files changed

+70
-49
lines changed

src/logic/refFn.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
1+
import { Refs, FieldReference } from "../types/formHandler";
12
import { isCheckboxInput, isMultipleSelect, isNativeControl, isRadioInput } from "../utils"
23

3-
export default (name: string, _refs: any, values: any) => (fieldRef: any) => {
4+
export default (name: string, _refs: Refs, values: any) => (fieldRef: any) => {
45
if (!fieldRef) {
56
delete _refs[name]
67
return
78
}
89
if (!fieldRef.nodeName || !isNativeControl(fieldRef)) {
910
//TODO: Correctly type this in order to expect a fixed data structure
10-
_refs[name] = {
11+
_refs[name].ref = {
1112
type: 'custom'
1213
}
1314
return
1415
}
15-
const isFirstRegister = !_refs[name] || (Array.isArray(_refs[name]) && isRadioInput(fieldRef) && !_refs[name].some((option: any) => option.value === fieldRef.value))
16+
const isFirstRegister = !_refs[name].ref
17+
|| (Array.isArray(_refs[name].ref)
18+
&& isRadioInput(fieldRef)
19+
&& (!(_refs[name].ref as FieldReference[])
20+
.some((option: any) => option.value === fieldRef.value)))
1621
if (isFirstRegister) {
17-
_refs[name] = isRadioInput(fieldRef) ? [...(_refs[name] || []), fieldRef] : fieldRef
22+
_refs[name].ref = isRadioInput(fieldRef)
23+
? [...(_refs[name].ref as FieldReference[] || [])
24+
, fieldRef]
25+
: fieldRef
1826
}
1927
if (isRadioInput(fieldRef)) {
2028
if (isFirstRegister && fieldRef.checked) {

src/logic/validateField.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { ValidateFieldParams } from './../types/logic';
22

3-
export default async ({ name, validations, values, formState, disabledFields }: ValidateFieldParams): Promise<void> => {
4-
if (!Object.keys(validations[name]).length) {
3+
export default async ({ name, values, formState, _refs }: ValidateFieldParams): Promise<void> => {
4+
if (!Object.keys(_refs[name]._validations).length) {
55
return
66
}
7-
if (!!disabledFields[name]) {
7+
if (_refs[name]._disabled) {
88
return
99
}
10-
for (const [validationName, validation] of Object.entries(validations[name])) {
10+
for (const [validationName, validation] of Object.entries(_refs[name]._validations)) {
1111
const result = await validation(values[name])
1212
formState.errors[name] = {
1313
...(result !== true && { [validationName]: result })

src/playground/App.vue

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,22 @@
44
<input v-bind="register('hello', {
55
useNativeValidation: true,
66
required: true,
7-
disabled: true,
87
})"><br>
98
<br>
109
<input type="radio" value="male" v-bind="register('gender')"> Male<br>
1110
<input type="radio" value="female" v-bind="register('gender')"> Female<br>
1211
<input type="radio" value="other" v-bind="register('gender')"> Other<br>
1312
<br>
14-
<input type="text">
1513
<button>Submit</button>
14+
<pre>{{ values }}</pre>
15+
<pre>{{ formState }}</pre>
1616
</form>
1717
</template>
1818

1919
<script setup lang="ts">
2020
import useFormHandler from '../useFormHandler';
21-
import { ref } from 'vue'
2221
23-
const { register, handleSubmit } = useFormHandler({});
22+
const { register, handleSubmit, values, formState } = useFormHandler({});
2423
const submitForm = (values: any) => {
2524
console.log(values)
2625
}

src/types/formHandler.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
export interface FieldReference {
2+
type: 'custom' | 'select' | 'select-multiple' | 'radio' | 'checkbox' | 'input' | 'textarea' | 'file' | 'range' | 'color' | 'date' | 'datetime-local' | 'email' | 'month' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'time' | 'url' | 'week';
3+
value?: any;
4+
checked?: boolean;
5+
selected?: boolean;
6+
options?: any;
7+
nodeName?: string;
8+
}
9+
10+
export interface WrappedReference {
11+
ref: FieldReference | FieldReference[];
12+
_validations: Validations;
13+
_disabled: boolean;
14+
_defaultValue: any;
15+
}
16+
17+
export type Refs = Record<string, WrappedReference>;
18+
119
/** Props for a base control */
220
export interface BaseControlProps {
321
/** Name of the control */

src/types/logic.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { FormState, Validations } from "./formHandler"
1+
import { FormState, Refs, Validations } from "./formHandler"
22

33
export interface ValidateFormParams {
4-
validations: Record<string, Validations>
5-
disabledFields: Record<string, boolean>
4+
_refs: Refs
65
formState: FormState
76
values: Record<string, any>
87
}

src/useFormHandler.ts

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ import {
1818
FormState,
1919
HandleSubmit,
2020
Register,
21-
IsValidForm
21+
IsValidForm,
22+
Refs
2223
} from './types/formHandler';
2324
import { reactive, readonly, watch } from 'vue'
2425
import { isEqual } from 'lodash-es'
2526
import { getNativeFieldValue, validateField, validateForm, getDefaultFieldValue, refFn } from './logic';
26-
import { isDefined } from './utils';
2727

2828
export const initialState = () => ({
2929
touched: {},
@@ -45,35 +45,22 @@ const useFormHandler: FormHandler = ({
4545
const values: Record<string, any> = reactive({ ...initialValues })
4646
const formState = reactive<FormState>({ ...initialState() })
4747

48-
let _validations: Record<string, Validations> = {}
49-
let _defaultValues: Record<string, any> = {}
50-
let _disabledFields: Record<string, boolean> = {}
51-
let _refs: Record<string, any> = {}
48+
let _refs: Refs = {}
5249

53-
const _getDefault = (name: string): any => _defaultValues[name] ?? getDefaultFieldValue(_refs[name])
50+
const _getDefault = (name: string): any => _refs[name]._defaultValue ?? getDefaultFieldValue(_refs[name].ref)
5451
const _getInitial = (name: string): any => initialValues[name] ?? _getDefault(name)
55-
56-
//TODO: check if validations and defaultValues can be hold up in under _refs object along with the ref information
5752
const _initControl: InitControl = (name, options) => {
58-
_validations = {
59-
..._validations,
60-
[name]: options.validations || {}
61-
}
62-
_defaultValues = {
63-
..._defaultValues,
64-
[name]: options.defaultValue
53+
const needsReset = options.disabled && _refs[name] && !_refs[name]._disabled
54+
_refs[name] = {
55+
..._refs[name] || {},
56+
_validations: options.validations || {},
57+
_defaultValue: options.defaultValue,
58+
_disabled: !!options.disabled,
6559
}
66-
if (isDefined(options.disabled)) {
67-
const wasDisabled = _disabledFields[name]
68-
_disabledFields = {
69-
..._disabledFields,
70-
[name]: !!options.disabled
71-
}
72-
if (!wasDisabled && options.disabled) {
73-
resetField(name)
74-
delete formState.errors[name]
75-
return
76-
}
60+
if (needsReset) {
61+
resetField(name)
62+
delete formState.errors[name]
63+
return
7764
}
7865
if (initialValues[name] === undefined && values[name] === undefined) {
7966
values[name] = _getDefault(name)
@@ -105,14 +92,11 @@ const useFormHandler: FormHandler = ({
10592
}
10693

10794
const triggerValidation: TriggerValidation = async (name) => {
108-
if (!Object.keys(_validations).length) {
109-
return
110-
}
11195
if (!name) {
112-
validateForm({ formState, values, validations: _validations, disabledFields: _disabledFields })
96+
validateForm({ formState, values, _refs })
11397
return
11498
}
115-
validateField({ formState, name, validations: _validations, values, disabledFields: _disabledFields })
99+
validateField({ formState, name, _refs, values })
116100
}
117101

118102
const setDirty: SetDirty = (name, dirty) => {
@@ -165,7 +149,20 @@ const useFormHandler: FormHandler = ({
165149
}
166150

167151
const setValue: SetValue = async (name, value = DEFAULT_FIELD_VALUE) => {
168-
if (!_disabledFields[name] || !interceptor || await interceptor({ name, value, values, formState, clearErrors, modifiedValues, resetField, resetForm, setError, triggerValidation })) {
152+
if (!_refs[name]._disabled
153+
&& (!interceptor
154+
|| await interceptor({
155+
name,
156+
value,
157+
values,
158+
formState,
159+
clearErrors,
160+
modifiedValues,
161+
resetField,
162+
resetForm,
163+
setError,
164+
triggerValidation
165+
}))) {
169166
values[name] = value
170167
setDirty(name, !isEqual(value, _getInitial(name)))
171168
}
@@ -213,7 +210,7 @@ const useFormHandler: FormHandler = ({
213210
isTouched: !!formState.touched[name],
214211
}),
215212
...(native !== false && {
216-
onChange: () => handleChange(name, getNativeFieldValue(_refs[name] as HTMLInputElement)),
213+
onChange: () => handleChange(name, getNativeFieldValue(_refs[name].ref)),
217214
}),
218215
...(useNativeValidation && {
219216
...nativeValidations

0 commit comments

Comments
 (0)