I have a problem with using Formik
and MUI
Autocomplete with multiple items.
For example: If you search by typing "Pencil", the issue is, it doesn't highlight it. Also you can still select it twice if you click it.
Expected outcome: We would be able to select an item or items. When an item is selected, its checkbox would be selected, and it would be highlighted.
Here's my codesandbox: CODESANDBOX
const TestAutocomplete = ({
field,
form: { touched, errors, setFieldValue, values },
...props
}) => {
const [inputValue, setInputValue] = useState("");
const debouncedInputValue = useDebounceValue(inputValue, 500);
const { data: response, isLoading } = useFetchSubledgersQuery({
pageNumber: 0,
pageSize: 50,
search: debouncedInputValue,
});
const handleChange = (_, newSelectedValues, reason) => {
if (reason === "clear") {
setFieldValue(field.name, []);
return;
}
setFieldValue(field.name, newSelectedValues);
};
const handleInputChange = (_, newInputValue) => {
setInputValue(newInputValue);
};
return (
<Autocomplete
{...field}
multiple
getOptionLabel={(option) =>
typeof option === "string" ? option : option?.name || ""
}
filterOptions={(x) => x}
options={response || []}
autoComplete
includeInputInList
fullWidth
noOptionsText={isLoading ? "Loading..." : "No data"}
onChange={handleChange}
inputValue={inputValue}
onInputChange={handleInputChange}
renderInput={(params) => (
<TextField
{...params}
{...props}
error={touched[field.name] && errors[field.name] ? true : false}
helperText={
touched[field.name] &&
errors[field.name] &&
String(errors[field.name])
}
/>
)}
renderOption={(props, option, { selected }) => (
<li {...props}>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={values?.[field.name]?.some(
(selectedValue) => selectedValue.id === option.id
)}
/>
{option?.name}
</li>
)}
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<Chip
key={option.id}
label={option.name}
{...getTagProps({ index })}
/>
))
}
/>
);
};
De-duplicate the auto-complete's "new value" prior to updating the form state.
Example:
const handleChange = (_, newSelectedValues, reason) => {
if (reason === "clear") {
setFieldValue(field.name, []);
return;
}
const idSet = new Set();
const deduplicated = newSelectedValues.reduce((values, current) => {
if (!idSet.has(current.id)) {
idSet.add(current.id);
values.push(current);
}
return values;
}, []);
setFieldValue(field.name, deduplicated);
};
Override the default function that checks if options are equal to selected values using the isOptionEqualToValue
prop.
<Autocomplete
.... all other current props ....
isOptionEqualToValue={(option, value) => option.id === value.id}
/>