π Bug - Autocomplete onSelectItem is not executed when an item is selected a second time
cmatthews-uwhealth opened this issue Β· comments
Forma 36 bug report
Summary
As reported earlier in this issue report, repeated clicks on an autocomplete item only trigger onSelectItem
with the first click, and clicks afterwards do not trigger onSelectItem
.
Environment
Microsoft Edge and Google Chrome, both when running locally and when used as an embedded field in a Contentful App.
Steps to reproduce
The behavior described below can be seen here: https://deploy-preview-61--uwhealth-contentful-ui-extensions.netlify.app/content-feed. Select a "Content Types" value to enable the "Filter Fields" Autocomplete component, then follow the steps below.
- Using an
<Autocomplete>
component withisGrouped
applied, click on the input box to deploy the dropdown menu of autocomplete items. - Click one of the options, the
onSelectItem
function will execute at this time. - Click the same option a second time. The
onSelectItem
function will not execute.
Note that theonSelectItem
function can be made to execute by clicking a different item and then clicking the original item again.
Expected results
The onSelectItem
function should execute every time an item is clicked, even on repeat clicks.
Actual results
The onSelectItem
function executes once when an item is clicked, but will not execute again no matter how many times the item is clicked. This bug is "reset" by clicking a different item.
Marking issue as stale since there was no activity for 30 days
Hey, thank you for reporting the issue. But could you provide a minimal example of your implementation? Because if you use a React State to handle your current selection it should work as I tried to reproduce the issue here in our playground but for me it toggles the selection.
In worst case you can reset the internal-form selectedItem of the Autocomplete by reset the selectedItem
property
<Autocomplete
{...args}
selectedItem={mySelectedState}
onSelectItem= {(item) => {
// do something with your selection
setMySelectedState('');
}
} />
Marking issue as stale since there was no activity for 30 days
edit: Actually I think we can ignore this β it is now working, and I think it may have something to do with using objects as items, but then using ==
or ===
equality checks, which require the same reference. Using some function that provides an equality check fixed it for me.
Just to comment that I am also running into this issue, it's a bit hard to work out exactly what is going on, but I am seeing that subsequent clicks on the same item do not trigger a subsequent call to the onSelectItem
/renderItem
.
Can we reopen this?
Screen.Recording.2024-07-17.at.13.11.18.mp4
import { Autocomplete, Stack } from '@contentful/f36-components';
import { SearchIcon } from '@contentful/f36-icons';
import { getStringMatch } from '@contentful/f36-utils';
import { useState } from 'react';
export const DropDownGroupedMinimal = () => {
const groupedItems = [
{
groupTitle: 'Group 1',
options: [
{
name: '1A',
},
{
name: '1B',
},
{
name: '1C',
},
],
},
{
groupTitle: 'Group 2',
options: [
{
name: '2A',
},
{
name: '2B',
},
{
name: '2C',
},
],
},
];
const [filteredItems, setFilteredItems] = useState(groupedItems);
const [selectedItems, setSelectedItems] = useState<{ name: string }[]>([]);
const handleInputValueChange = (value: string) => {
const newFilteredItems = groupedItems.map((group) => ({
groupTitle: group.groupTitle,
options: group.options.filter((option) => option.name.toLowerCase().includes(value.toLowerCase())),
}));
setFilteredItems(newFilteredItems);
};
const handleSelectItem = (item: { name: string }) => {
console.log(`Clicked on ${item.name} with [${selectedItems.map((item) => item.name).join(',')}]`);
setSelectedItems((prevItems) => {
if (prevItems.some((i) => item === item)) {
console.log(`Removing ${item.name}`);
return prevItems.filter((prevItem) => prevItem.name !== item.name);
} else {
console.log(`Adding ${item.name}`);
return [...prevItems, item];
}
});
};
return (
<Stack flexDirection="column" alignItems="start">
<Autocomplete
isGrouped={true}
items={filteredItems}
onInputValueChange={handleInputValueChange}
onSelectItem={handleSelectItem}
itemToString={(item) => item.name}
textOnAfterSelect="clear"
closeAfterSelect={false}
icon={<SearchIcon variant="muted" />}
renderItem={(item, inputValue) => {
const { before, match, after } = getStringMatch(item.name, inputValue);
return (
<>
{before}
<b>{match}</b>
{after}
{selectedItems.some((i) => i.name === item.name) ? ' (selected)' : ''}
</>
);
}}
/>
</Stack>
);
};
Actually, I think we can close this β see edit above!