1
1
import { nextTick , reactive , ref , toRefs , unref } from 'vue'
2
2
import setWith from 'lodash.setwith'
3
+ import toPath from 'lodash.topath'
3
4
import { VALIDATION_MODE } from '../shared/constant'
4
5
import {
5
6
get ,
@@ -90,7 +91,21 @@ export function creatFormControl<
90
91
fieldName ? get ( _formState . errors , fieldName ) : _formState . errors
91
92
92
93
const _removeFormStateError = ( fieldName : FieldsKey ) => {
93
- unset ( _formState . errors , fieldName )
94
+ if ( isEmptyObject ( _formState . errors ) ) {
95
+ return
96
+ }
97
+
98
+ const paths = toPath ( fieldName )
99
+
100
+ if ( paths . length !== 1 ) {
101
+ let error : any = _formState . errors
102
+ for ( const path of paths . slice ( 0 , - 1 ) ) {
103
+ error = error [ path ]
104
+ }
105
+ unset ( error , paths . at ( - 1 ) )
106
+ } else {
107
+ unset ( _formState . errors , fieldName )
108
+ }
94
109
}
95
110
96
111
const _setFields = ( name : FieldsKey , fieldOptions : Partial < Field > ) => {
@@ -102,31 +117,51 @@ export function creatFormControl<
102
117
}
103
118
104
119
const _getDefaultValue = ( field : FieldsKey ) => {
105
- return _defaultValues [ field as string ]
120
+ return _defaultValues [ field ]
106
121
}
107
122
108
123
const _setValidating = ( isValidating : boolean ) =>
<
F438
tr class="diff-line-row">109
124
_setFormState ( { isValidating } )
110
125
111
- const _getFieldProp = ( name : FieldsKey , prop : keyof Field ) => {
112
- return get ( _fields [ name ] , prop )
126
+ const _getFieldDom = ( name : FieldsKey ) => {
127
+ return _fields [ name ] . el . value as FieldElement | undefined
113
128
}
114
129
115
- const _getFieldDom = ( name : FieldsKey ) => {
116
- return _getFieldProp ( name , 'el' ) as FieldElement | undefined
130
+ const _isDirtyField = ( fieldName : FieldsKey ) => {
131
+ const field = _fields [ fieldName ]
132
+
133
+ if ( ! field ) {
134
+ return false
135
+ }
136
+
137
+ const inputVal = field . inputValue . value
138
+ const defaultVal = _getDefaultValue ( fieldName )
139
+ const el = field . el . value
140
+
141
+ if ( ! isUndefined ( defaultVal ) ) {
142
+ if ( isRadioOrCheckboxInput ( el ) ) {
143
+ return inputVal !== defaultVal && el . checked !== defaultVal
144
+ } else {
145
+ return inputVal !== defaultVal
146
+ }
147
+ }
148
+
149
+ if ( isRadioOrCheckboxInput ( el ) ) {
150
+ return inputVal !== el . checked
151
+ } else {
152
+ return inputVal !== ''
153
+ }
117
154
}
118
155
119
156
const _getDirtyFields = ( handleIsDirty = true ) => {
120
157
const dirtyFields = { } as TFormState [ 'dirtyFields' ]
121
158
122
- Object . entries ( _fields ) . forEach ( ( [ key , val ] ) => {
123
- if (
124
- val . isDirty ||
125
- ( _getDefaultValue ( key ) &&
126
- val . inputValue . value !== _getDefaultValue ( key ) ) ||
127
- val . inputValue . value !== ''
128
- ) {
159
+ Object . keys ( _fields ) . forEach ( ( key ) => {
160
+ if ( _isDirtyField ( key ) ) {
129
161
set ( dirtyFields , key , true )
162
+ } else {
163
+ unset ( dirtyFields , key )
164
+ _fields [ key ] . isDirty = false
130
165
}
131
166
} )
132
167
@@ -293,6 +328,7 @@ export function creatFormControl<
293
328
}
294
329
295
330
const _onChange = async ( name ?: FieldsKey ) => {
331
+ _getDirtyFields ( )
296
332
await trigger ( name )
297
333
298
334
_handleIsValidFields ( )
@@ -318,13 +354,23 @@ export function creatFormControl<
318
354
}
319
355
320
356
Object . entries ( values ) . forEach ( ( [ key , val ] ) => {
321
- _fields [ key ] . inputValue . value = val
357
+ const el = _fields [ key ] . el . value
358
+
359
+ if ( ! keepStateOptions . keepDefaultValues ) {
360
+ _formState . defaultValues [ key as keyof TFieldValues ] = val
361
+ }
362
+ if ( ! keepStateOptions . keepValues ) {
363
+ _fields [ key ] . inputValue . value = val
364
+ }
365
+ if ( isRadioOrCheckboxInput ( el ) ) {
366
+ el . checked = val
367
+ }
322
368
} )
323
369
324
370
const dirtyFields = _getDirtyFields ( false )
325
371
326
372
if ( ! keepStateOptions ) {
327
- keepStateOptions = { } as any
373
+ keepStateOptions = { }
328
374
}
329
375
330
376
_setFormState ( {
@@ -335,12 +381,13 @@ export function creatFormControl<
335
381
? _formState . submitCount
336
382
: 0 ,
337
383
errors : keepStateOptions ! . keepErrors ? _formState . errors : { } ,
338
- isDirty : keepStateOptions ! . keepDirty
384
+ isDirty : keepStateOptions . keepDirtyValues
339
385
? _formState . isDirty
340
386
: ! isEmptyObject ( dirtyFields ) ,
341
- dirtyFields : keepStateOptions ! . keepDirty
342
- ? _formState . dirtyFields
343
- : dirtyFields ,
387
+ dirtyFields :
388
+ keepStateOptions ! . keepDirty || keepStateOptions . keepDirtyValues
389
+ ? _formState . dirtyFields
390
+ : dirtyFields ,
344
391
isSubmitting : false ,
345
392
isSubmitSuccessful : false ,
346
393
isValid : keepStateOptions ! . keepIsValid ? _formState . isValid : false ,
@@ -384,24 +431,33 @@ export function creatFormControl<
384
431
}
385
432
}
386
433
387
- const setError : UseFormSetError < FieldsKey > = ( fieldName , error , config ) => {
388
- if ( ! config ) {
389
- config = {
390
- shouldFocusError : true ,
391
- }
392
- }
434
+ const setError : UseFormSetError < FieldsKey > = (
435
+ fieldName ,
436
+ error ,
437
+ config = { shouldFocusError : true }
438
+ ) => {
439
+ _setFormStateError ( fieldName , {
440
+ message : '' ,
441
+ ...error ,
442
+ el : _fields [ fieldName ] . el ,
443
+ } as FieldError )
393
444
394
- _setFormStateError ( fieldName , error )
445
+ _setFormState ( {
446
+ isValid : false ,
447
+ } )
395
448
396
- if ( config . shouldFocusError )
449
+ if ( config . shouldFocusError ) {
397
450
handleValidateError ( error , true , _getFieldDom ( fieldName ) )
451
+ }
398
452
}
399
453
400
454
const clearErrors : UseFormClearErrors < FieldsKey > = ( fieldName ) => {
401
455
if ( isUndefined ( fieldName ) ) {
402
456
set ( _formState , 'errors' , { } )
403
457
} else {
404
- if ( ! isArray ( fieldName ) ) fieldName = [ fieldName ]
458
+ if ( ! isArray ( fieldName ) ) {
459
+ fieldName = [ fieldName ]
460
+ }
405
461
406
462
fieldName . forEach ( ( name ) => {
407
463
_removeFormStateError ( name )
@@ -473,7 +529,9 @@ export function creatFormControl<
473
529
fieldName ,
474
530
options ?: RegisterOptions
475
531
) => {
476
- if ( isUndefined ( options ) ) options = { }
532
+ if ( isUndefined ( options ) ) {
533
+ options = { }
534
+ }
477
535
478
536
let isModelValue = false
479
537
let field = get ( _fields , fieldName )
@@ -499,8 +557,14 @@ export function creatFormControl<
499
557
isUnregistered : false ,
500
558
el : ref ( null ) ,
501
559
} )
502
-
503
560
field = get ( _fields , fieldName )
561
+
562
+ nextTick ( ( ) => {
563
+ const el = field . el . value
564
+ if ( el instanceof HTMLElement && isRadioOrCheckboxInput ( el ) ) {
565
+ el . checked = defaultVal === '' ? false : defaultVal
566
+ }
567
+ } )
504
568
}
505
569
506
570
const addEventListenerToElement = ( ) => {
@@ -509,14 +573,12 @@ export function creatFormControl<
509
573
}
510
574
511
575
const el = getFormEl ( field . el )
512
- _setFields ( fieldName , { ... _fields [ fieldName ] , el } )
576
+ _fields [ fieldName ] . el . value = el
513
577
514
578
if ( isRadioOrCheckboxInput ( el ) ) {
515
579
set ( _defaultValues , fieldName as string , ! ! defaultVal )
516
580
}
517
581
518
- set ( _defaultValues , fieldName as string , defaultVal )
519
-
520
582
// bind validate mode
521
583
if ( isFieldElement ( el ) ) {
522
584
if ( validationModeBeforeSubmit . isOnBlur ) {
@@ -596,7 +658,7 @@ export function creatFormControl<
596
658
if ( ! options . keepValue ) {
597
659
_setFieldsValue (
598
660
fieldName as string ,
599
- _defaultValues [ fieldName as string ] || ''
661
+ _defaultValues [ fieldName ] || ( '' as any )
600
662
)
601
663
}
602
664
0 commit comments