react-admin
react-admin copied to clipboard
ReferenceArrayInput with AutocompleteArrayInput clearing input
I wanted to create AutocompleteArrayInput within ReferenceArrayInput,
What you were expecting:
I expected to be able to choose from the list elements just fine.
What happened instead:
Whenever I start typing in the autocompleteArrayInput, when there is more than one item already selected, the choice list gets updated, then the value I have written into the input gets cleared, and the suggestion list gets updated again. It makes it almost impossible to use the form.
Steps to reproduce:
I am using react-admin-firebase (not sure if that's important). I created a form with an input:
<ReferenceArrayInput
source="qualifyingTasks"
reference="Tasks"
>
<AutocompleteArrayInput
filterToQuery={(q) => ({name: q})}
optionText={(record) => record.name}
/>
</ReferenceArrayInput>
It seems to be enough to reproduce the issue. Just keep adding tasks to the form and eventualy it will end up clearing the typed text.
Can't seem to be able to reproduce the issue using the ra-data-fakerest, It might be related to react-admin-firebase library somehow.
Environment
- React-admin version: 4.3.3
- Last version that did not exhibit the issue (if applicable): -
- React version: 17.0.2
- Browser: Chrome
- Stack trace (in case of a JS error): -
I seem to have managed to mitigate the issue by setting clearOnBlur
option to false. Now the question is why does this happen exactly?
I had the similar issue on react-admin 4.3.1. An update to last 4.3.4 version improved it to a usable level in my case without clearOnBlur={false}
. It is still happen but less often.
After all I also ended up with clearOnBlur={false}
to have robust solution. Also for that moment couldn't reproduce it using default CodeSanbox. I am using react-admin with api-platform.
If you can't reproduce it with the codesandbox, it's possible that it's caused by a third-party data provider. Another possibility is that the CodeSandbox shows a small delay for dataProvider responses, and this is a race condition that only shows for larger delays.
In any case, we need a reproduction to start investigating this issue.
@fzaninotto it seems that I have managed to reproduce this bug. Please check the following CodeSandbox or the repo.
Steps to reproduce the bug:
- Open users ->
user #112
(url path/#/user/112
) - Start typing
Another reproduction was passed in #8410
I don't reproduce this issue in v4.6.1 in our storybook with the following (edited) story inside https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/input/AutocompleteArrayInput.stories.tsx :
const BookEditWithReference = () => (
<Edit
mutationMode="pessimistic"
mutationOptions={{
onSuccess: data => {
console.log(data);
},
}}
>
<SimpleForm>
<ReferenceArrayInput reference="authors" source="author">
<AutocompleteArrayInput
fullWidth
//optionText="name"
filterToQuery={q => ({ name: q })}
optionText={record => record.name}
/>
</ReferenceArrayInput>
</SimpleForm>
</Edit>
);
export const InsideReferenceArrayInput = () => (
<Admin dataProvider={dataProviderWithAuthors} history={history}>
<Resource name="authors" />
<Resource name="books" edit={BookEditWithReference} />
</Admin>
);
Hence, I'll consider this issue fixed.
Hi @slax57 Thank you for your reply, but I'm afraid that the issue is still here.
I have updated and simplified the repro of #8181 (github, codesandbox) and the repro of #8410 (github, codesandbox)
@magicxor thanks for your reply and for the sandboxes.
Do you think you could provide a sandbox based on the simple example? I'm having a hard time working with sandboxes pointing to another project because it asks me for permissions to open them and I can't change the code easily.
Thanks
Besides, I had a quick look at the code from your reproduction project, and saw there are many places where you try advanced and custom features, that are beyond the use-cases we support officially.
For instance:
- Having an
<Edit>
inside a<Show>
- Overriding the
record
in the<SimpleForm>
only - Having the
achievements
stored actually on another resource thanuser
- Providing a custom
format
with noparse
- And so on...
It is still too complex and there are too many places prone to error for us to work with.
When taking your repo and just changing UserEdit
with the following content it works flawlessly:
export const UserEdit = () => {
return (
<Edit>
<SimpleForm>
<ReferenceArrayInput
label="Achievements"
source="achievements"
reference="achievement"
allowEmpty
fullWidth
>
<AutocompleteArrayInput
optionText={(o) => o.name}
//format={formatFunc}
filterToQuery={createSearchFilter}
disableClearable
clearOnBlur={false}
fullWidth
/>
</ReferenceArrayInput>
</SimpleForm>
</Edit>
);
};
Hence, I'll still consider this issue fixed, unless you can provide a simpler repro, based on the simple example, and with supported (i.e. documented) use-cases only.
@slax57
Do you think you could provide a sandbox based on the simple example?
Sure. Please take a look: https://codesandbox.io/s/stupefied-cray-7n3gbo?file=/src/index.tsx
Basically, my API returns a post:
{
id: 10,
title: 'Totam vel quasi a odio et nihil',
teaser:
'Excepturi veritatis velit rerum nemo voluptatem illum tempora eos. Et impedit sed qui et iusto. A alias asperiores quia quo.',
body:
'<p>Voluptas iure consequatur repudiandae quibusdam iure. Quibusdam consequatur sit cupiditate aut eum iure. Provident ut aut est itaque ut eligendi sunt.</p><p>Odio ipsa dolore rem occaecati voluptatum neque. Quia est minima totam est dicta aliquid sed. Doloribus ea eligendi qui odit. Consectetur aut illum aspernatur exercitationem ut. Distinctio sapiente doloribus beatae natus mollitia. Nostrum cum magni autem expedita natus est nulla totam.</p><p>Et possimus quia aliquam est molestiae eum. Dicta nostrum ea rerum omnis. Ut hic amet sequi commodi voluptatem ut. Nulla magni totam placeat asperiores error.</p>',
views: 721,
average_note: 4.121,
commentable: true,
published_at: new Date('2012-10-19'),
tags: [
// my API returns objects, not just IDs:
{
id: 2,
name: 'Technology',
published: false,
},
{
id: 4,
name: 'Photo',
published: false,
}
],
category: 'lifestyle'
}
I want to edit the tags
property of this post:
export const formatFunc = (tags: any[]) => tags.map((tag: { id: number }) => tag.id);
export const parseFunc = (tagIds: number[]) => tagIds.map((id: number) => ({ id }));
<ReferenceArrayInput
reference="tags"
source="tags"
label="Tags"
>
<AutocompleteArrayInput
optionText={'name'}
format={formatFunc}
parse={parseFunc}
filterToQuery={q => ({ name: q })}
/>
</ReferenceArrayInput>
But search doesn't work properly in this input:
@magicxor Thanks for the repro.
tags: [
// my API returns objects, not just IDs:
{
id: 2,
name: 'Technology',
published: false,
},
{
id: 4,
name: 'Photo',
published: false,
}
],
// my API returns objects, not just IDs:
That's actually the cause of the error. <ReferenceArrayInput>
only supports an array of ids as source
.
With format
and parse
you can only change the format of the value in the input element, but the value in the record needs to be of the expected shape.
If your API returns objects you probably need to tweak your dataProvider to transform them into an array of ids to be usable by <ReferenceArrayInput>
.
Btw @magicxor , you might be interested in this PR if you are looking for a way to add lifecycle callbacks to your dataProvider :wink: