File tree 4 files changed +44
-6
lines changed
packages/ra-ui-materialui/src
4 files changed +44
-6
lines changed Original file line number Diff line number Diff line change @@ -12,7 +12,12 @@ import {
12
12
import { SaveButton } from './SaveButton' ;
13
13
import { SimpleForm , Toolbar } from '../form' ;
14
14
import { Edit } from '../detail' ;
15
- import { TextInput } from '../input' ;
15
+ import {
16
+ TextInput ,
17
+ ArrayInput ,
18
+ SimpleFormIterator ,
19
+ NumberInput ,
20
+ } from '../input' ;
16
21
import { AdminContext } from '../AdminContext' ;
17
22
18
23
const invalidButtonDomProps = {
@@ -400,4 +405,37 @@ describe('<SaveButton />', () => {
400
405
)
401
406
) ;
402
407
} ) ;
408
+
409
+ it ( 'should not be enabled if no inputs have changed' , async ( ) => {
410
+ render (
411
+ < AdminContext dataProvider = { testDataProvider ( ) } >
412
+ < SimpleForm
413
+ resource = "myresource"
414
+ onSubmit = { jest . fn }
415
+ defaultValues = { {
416
+ test : 'test' ,
417
+ } }
418
+ >
419
+ < TextInput source = "test" />
420
+ < ArrayInput resource = "foo" source = "arr" >
421
+ < SimpleFormIterator >
422
+ < NumberInput source = "id" />
423
+ </ SimpleFormIterator >
424
+ </ ArrayInput >
425
+ </ SimpleForm >
426
+ </ AdminContext >
427
+ ) ;
428
+
429
+ const testInput = screen . getByLabelText (
430
+ 'resources.myresource.fields.test'
431
+ ) ;
432
+ fireEvent . focus ( testInput ) ;
433
+ fireEvent . blur ( testInput ) ;
434
+
435
+ await waitFor ( ( ) =>
436
+ expect ( screen . getByLabelText ( 'ra.action.save' ) [ 'disabled' ] ) . toEqual (
437
+ true
438
+ )
439
+ ) ;
440
+ } ) ;
403
441
} ) ;
Original file line number Diff line number Diff line change @@ -65,7 +65,9 @@ export const SaveButton = <RecordType extends RaRecord = any>(
65
65
const translate = useTranslate ( ) ;
66
66
const form = useFormContext ( ) ;
67
67
const saveContext = useSaveContext ( ) ;
68
- const { isDirty, isValidating, isSubmitting } = useFormState ( ) ;
68
+ const { dirtyFields, isValidating, isSubmitting } = useFormState ( ) ;
69
+ // useFormState().isDirty might differ from useFormState().dirtyFields (https://github.com/react-hook-form/react-hook-form/issues/4740)
70
+ const isDirty = Object . keys ( dirtyFields ) . length > 0 ;
69
71
// Use form isDirty, isValidating and form context saving to enable or disable the save button
70
72
// if alwaysEnable is undefined
71
73
const disabled = valueOrDefault (
Original file line number Diff line number Diff line change @@ -223,7 +223,7 @@ describe('<DateTimeInput />', () => {
223
223
const onSubmit = jest . fn ( ) ;
224
224
render (
225
225
< AdminContext dataProvider = { testDataProvider ( ) } >
226
- < SimpleForm onSubmit = { onSubmit } >
226
+ < SimpleForm mode = "onBlur" onSubmit = { onSubmit } >
227
227
< DateTimeInput
228
228
{ ...defaultProps }
229
229
validate = { required ( ) }
@@ -245,7 +245,6 @@ describe('<DateTimeInput />', () => {
245
245
target : { value : '' } ,
246
246
} ) ;
247
247
fireEvent . blur ( input ) ;
248
- fireEvent . click ( screen . getByText ( 'ra.action.save' ) ) ;
249
248
await waitFor ( ( ) => {
250
249
expect (
251
250
screen . queryByText ( 'ra.validation.required' )
Original file line number Diff line number Diff line change @@ -213,7 +213,7 @@ describe('<TimeInput />', () => {
213
213
const onSubmit = jest . fn ( ) ;
214
214
render (
215
215
< AdminContext dataProvider = { testDataProvider ( ) } >
216
- < SimpleForm onSubmit = { onSubmit } >
216
+ < SimpleForm mode = "onBlur" onSubmit = { onSubmit } >
217
217
< TimeInput { ...defaultProps } validate = { required ( ) } />
218
218
</ SimpleForm >
219
219
</ AdminContext >
@@ -232,7 +232,6 @@ describe('<TimeInput />', () => {
232
232
target : { value : '' } ,
233
233
} ) ;
234
234
fireEvent . blur ( input ) ;
235
- fireEvent . click ( screen . getByText ( 'ra.action.save' ) ) ;
236
235
await waitFor ( ( ) => {
237
236
expect (
238
237
screen . queryByText ( 'ra.validation.required' )
You can’t perform that action at this time.
0 commit comments