Skip to content

Commit

Permalink
Merge pull request #8296 from marmelab/autocomplete-isrequired
Browse files Browse the repository at this point in the history
Fix `AutocompleteInput` displays empty choice when `validate={required()}`
  • Loading branch information
fzaninotto authored Oct 25, 2022
2 parents 1536c13 + 65f940f commit 4bde333
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 29 deletions.
80 changes: 80 additions & 0 deletions packages/ra-ui-materialui/src/input/AutocompleteInput.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {
FormDataConsumer,
required,
testDataProvider,
TestTranslationProvider,
useRecordContext,
Expand Down Expand Up @@ -121,6 +122,85 @@ describe('<AutocompleteInput />', () => {

expect(input.value).toEqual('Default');
});

it('should display the emptyText when input is not required', async () => {
const emptyText = 'Default';
render(
<AdminContext dataProvider={testDataProvider()}>
<SimpleForm
onSubmit={jest.fn()}
defaultValues={{ role: 1 }}
>
<AutocompleteInput
emptyText={emptyText}
{...defaultProps}
choices={[]}
/>
</SimpleForm>
</AdminContext>
);
fireEvent.click(
await screen.findByLabelText('resources.users.fields.role')
);
await waitFor(() => {
expect(screen.queryAllByRole('option').length).toEqual(1);
});
expect(screen.queryByText('Default')).not.toBeNull();
});

it('should not display the emptyText when validate equals required', async () => {
const emptyText = 'Default';
render(
<AdminContext dataProvider={testDataProvider()}>
<SimpleForm
onSubmit={jest.fn()}
defaultValues={{ role: 1 }}
>
<AutocompleteInput
emptyText={emptyText}
{...defaultProps}
choices={[]}
validate={required()}
/>
</SimpleForm>
</AdminContext>
);
fireEvent.click(
await screen.findByLabelText('resources.users.fields.role *')
);
await waitFor(() => {
expect(screen.queryAllByRole('option').length).toEqual(0);
});
expect(screen.queryByText('Default')).toBeNull();
await screen.findByText('No options');
});

it('should not display the emptyText when isRequired is true', async () => {
const emptyText = 'Default';
render(
<AdminContext dataProvider={testDataProvider()}>
<SimpleForm
onSubmit={jest.fn()}
defaultValues={{ role: 1 }}
>
<AutocompleteInput
emptyText={emptyText}
{...defaultProps}
choices={[]}
isRequired
/>
</SimpleForm>
</AdminContext>
);
fireEvent.click(
await screen.findByLabelText('resources.users.fields.role *')
);
await waitFor(() => {
expect(screen.queryAllByRole('option').length).toEqual(0);
});
expect(screen.queryByText('Default')).toBeNull();
await screen.findByText('No options');
});
});

describe('optionValue', () => {
Expand Down
55 changes: 26 additions & 29 deletions packages/ra-ui-materialui/src/input/AutocompleteInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,32 @@ export const AutocompleteInput = <

const finalEmptyText = emptyText ?? '';

const {
id,
field,
isRequired,
fieldState: { error, invalid, isTouched },
formState: { isSubmitted },
} = useInput({
defaultValue,
id: idOverride,
field: fieldOverride,
fieldState: fieldStateOverride,
formState: formStateOverride,
isRequired: isRequiredOverride,
onBlur,
onChange,
parse,
format,
resource,
source,
validate,
...rest,
});

const finalChoices = useMemo(
() =>
isRequiredOverride || multiple
isRequired || multiple
? allChoices
: [
{
Expand All @@ -213,36 +236,14 @@ export const AutocompleteInput = <
allChoices,
emptyValue,
finalEmptyText,
isRequiredOverride,
isRequired,
multiple,
optionText,
optionValue,
translate,
]
);

const {
id,
field,
isRequired,
fieldState: { error, invalid, isTouched },
formState: { isSubmitted },
} = useInput({
defaultValue,
id: idOverride,
field: fieldOverride,
fieldState: fieldStateOverride,
formState: formStateOverride,
onBlur,
onChange,
parse,
format,
resource,
source,
validate,
...rest,
});

const selectedChoice = useSelectedChoice<
OptionType,
Multiple,
Expand Down Expand Up @@ -537,11 +538,7 @@ If you provided a React element for the optionText prop, you must also provide t
label={label}
source={source}
resource={resourceProp}
isRequired={
typeof isRequiredOverride !== 'undefined'
? isRequiredOverride
: isRequired
}
isRequired={isRequired}
/>
}
error={
Expand Down

0 comments on commit 4bde333

Please sign in to comment.