Как воссоздать поведение onChange Autocomplete Material UI при нажатие на кнопку Enter
Добрый день, коллеги!
Я использую Autocomplete Material UI. Мне нужно реализовать следующую задачу. При открытие Autocomplete подгружаются данные, и если в выпадающем списке одно только значение, то пользователь нажимает Enter и это значение автоматически становится выбранным. Как сделать так чтоб при нажатие на Enter значение было выбрано, как при функции onChange.
export const AsyncAutoComplete: React.FC<IPropsAsyncAutocomplete> = ({
pathname,
searchParameters = {},
fieldName,
label,
onSelectedEntities,
isNoValid = false,
helperText = '',
isMultiple
}) => {
const initSearchValue = (): string => {
const par = searchParameters[fieldName];
if (!par) {
return '';
}
if (Array.isArray(par)) {
return par[0];
}
return par;
};
const loadRec = useHttp<IHydraGet<IEntity>>();
const [list, setList] = useState<IEntity[]>([]);
const [open, setOpen] = useState<boolean>(false);
const [total, setTotal] = useState<number>(0);
const [searchValue, setSearchValue] = useState(initSearchValue);
const [page, setPage] = useState<number>(Number(searchParameters?.page) || 1);
const [isUpdateList, setIsUpdateList] = useState(false);
const onChange = (
event: ChangeEvent<{}>,
value: IEntity[] | [] | IEntity | null
) => {
let newValue: IEntity[] = [];
if (Array.isArray(value)) {
newValue = value;
} else {
value && newValue.push(value);
}
onSelectedEntities(newValue);
};
const onInputChange = (event: ChangeEvent<{}>, value: string) => {
setList([]);
setPage(FIRST_PAGE);
setSearchValue(value);
setIsUpdateList(false);
onSelectedEntities([]);
};
const onScrollAutocomplete = (event: React.UIEvent<HTMLElement>) => {
const listboxNode = event.currentTarget;
if (
listboxNode.scrollHeight - listboxNode.scrollTop <=
listboxNode.clientHeight + DELTA_SCROLL &&
list.length < total &&
!isUpdateList
) {
setIsUpdateList(true);
setPage(page + 1);
}
};
const onKeyUpTextField = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter' && list.length === 1) {
event.preventDefault();
onChange(event, list[0]);
setSearchValue(list[0][fieldName]);
setOpen(false);
}
};
useEffect(() => {
const newSearchParameters = {
...searchParameters,
page: page.toString(),
[fieldName]: searchValue
};
const url = getQueryString(pathname, newSearchParameters);
loadRec.updateResponse({ url });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [page, searchValue]);
useEffect(() => {
if (loadRec.data) {
let newList = [];
if (isUpdateList) {
newList = list.concat(loadRec.data['hydra:member']);
} else {
newList = loadRec.data['hydra:member'];
}
setTotal(loadRec.data['hydra:totalItems']);
setList(newList);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [loadRec.data]);
return (
<Autocomplete
multiple={isMultiple}
open={open}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
options={list}
getOptionLabel={(option) => {
return option[fieldName];
}}
onInputChange={onInputChange}
onChange={onChange}
loading={loadRec.isLoading}
loadingText={ETitle.asyncAutocompleteLoadingText}
noOptionsText={
loadRec.error?.message || ETitle.asyncAutocompleteNoOptionsText
}
getOptionSelected={(option, value) => {
return option[fieldName] === value[fieldName];
}}
ListboxProps={{
onScroll: onScrollAutocomplete,
style: {
maxHeight: '200px'
}
}}
renderInput={(params) => {
return (
<TextField
{...params}
onKeyUp={onKeyUpTextField}
error={!!loadRec.error || isNoValid}
helperText={helperText}
label={label}
variant='outlined'
margin='normal'
value={searchValue}
InputProps={{
...params.InputProps,
endAdornment: (
<>
{loadRec.isLoading && open ? (
<CircularProgress color='secondary' size={30} />
) : null}
{params.InputProps.endAdornment}
</>
)
}}
/>
);
}}
/>
);
};