Задать вопрос
@EvgenJunior

Как воссоздать поведение onChange Autocomplete Material UI при нажатие на кнопку Enter?

Как воссоздать поведение 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}
                </>
              )
            }}
          />
        );
      }}
    />
  );
};
  • Вопрос задан
  • 260 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы