【问题标题】:Material UI Autocomplete - Disable listbox after the item selectionMaterial UI Autocomplete - 选择项目后禁用列表框
【发布时间】:2021-07-03 11:26:42
【问题描述】:

我正在借助 Material-UI headless useAutoComplete 钩子在 React.js 中创建一个自动完成组件。组件工作正常。当用户尝试输入任何字符时,Listbox 将自动打开。

但问题是当用户选择任何东西并注意输入元素时,ListBox 会重新打开。我怎样才能防止这种情况发生?

代码沙盒:

代码:

import React from 'react';
import useAutocomplete from '@material-ui/lab/useAutocomplete';

function AutocompleteComponent(props) {
  const { data } = props;

  const [value, setValue] = React.useState('');
  const [isOpen, setIsOpen] = React.useState(false);

  const handleOpen = function () {
    if (value.length > 0) {
      setIsOpen(true);
    }
  };

  const handleInputChange = function (event, newInputValue) {
    setValue(newInputValue);
    if (newInputValue.length > 0) {
      setIsOpen(true);
    } else {
      setIsOpen(false);
    }
  };

  const {
    getRootProps,
    getInputProps,
    getListboxProps,
    getOptionProps,
    groupedOptions
  } = useAutocomplete({
    id: 'form-control',
    options: data,
    autoComplete: true,
    open: isOpen, // Manually control
    onOpen: handleOpen, // Manually control
    onClose: () => setIsOpen(false), // Manually control
    inputValue: value, // Manually control
    onInputChange: handleInputChange, // Manually control
    getOptionLabel: (option) => option.name
  });

  const listItem = {
    className: 'form-control__item'
  };

  return (
    <div className="app">
      <div className="form">
        <div {...getRootProps()}>
          <input
            type="text"
            className="form-control"
            placeholder="Location"
            {...getInputProps()}
          />
        </div>
        {groupedOptions.length > 0 && (
          <ul
            className="form-control__box"
            aria-labelledby="autocompleteMenu"
            {...getListboxProps()}
          >
            {groupedOptions.map((option, index) => {
              return (
                <li {...getOptionProps({ option, index })} {...listItem}>
                  <div>{option.name}</div>
                </li>
              );
            })}
          </ul>
        )}
      </div>
    </div>
  );
}

export default AutocompleteComponent;

【问题讨论】:

  • 我刚刚更新了您的代码sandbox 代码。请查阅。一旦用户选择了某个值,我们只是使用下面的代码禁用输入。 disabled={Boolean(value) &amp;&amp; !isOpen} 虽然,这会禁用在用户选择某些值后重新编辑选择的能力。
  • @Junaid 不应该禁用自动完成功能,用户可以重新输入任何匹配结果。

标签: reactjs material-ui


【解决方案1】:

您可以将 selectedItem 存储在一个状态中,并在 handleOpen 中使用它来决定是否必须显示列表。 对于设置 selectedItem,您可以修改 getOptionProps 提供的默认单击

import React from 'react';
import useAutocomplete from '@material-ui/lab/useAutocomplete';

function AutocompleteComponent(props) {
  const { data } = props;

  const [value, setValue] = React.useState('');
  const [isOpen, setIsOpen] = React.useState(false);
  const [selectedItem, setSelectedItem] = React.useState('');

  const handleOpen = function () {
    if (value.length > 0 && selectedItem !== value) {
      setIsOpen(true);
    }
  };

  const handleInputChange = function (event, newInputValue) {
    setValue(newInputValue);
    if (newInputValue.length > 0) {
      setIsOpen(true);
    } else {
      setIsOpen(false);
    }
  };

  const {
    getRootProps,
    getInputProps,
    getListboxProps,
    getOptionProps,
    groupedOptions
  } = useAutocomplete({
    id: 'form-control',
    options: data,
    autoComplete: true,
    open: isOpen, // Manually control
    onOpen: handleOpen, // Manually control
    onClose: () => setIsOpen(false), // Manually control
    inputValue: value, // Manually control
    onInputChange: handleInputChange, // Manually control
    getOptionLabel: (option) => option.name
  });

  const listItem = {
    className: 'form-control__item'
  };

  return (
    <div className="app">
      <div className="form">
        <div {...getRootProps()}>
          <input
            type="text"
            className="form-control"
            placeholder="Location"
            {...getInputProps()}
          />
        </div>
        {groupedOptions.length > 0 && (
          <ul
            className="form-control__box"
            aria-labelledby="autocompleteMenu"
            {...getListboxProps()}
          >
            {groupedOptions.map((option, index) => {
              return (
                <li
                  {...getOptionProps({ option, index })}
                  {...listItem}
                  onClick={(ev) => {
                    setSelectedItem(option.name);
                    getOptionProps({ option, index }).onClick(ev);
                  }}
                >
                  <div>{option.name}</div>
                </li>
              );
            })}
          </ul>
        )}
      </div>
    </div>
  );
}

export default AutocompleteComponent;

【讨论】:

    【解决方案2】:

    您可以在应用之前修改传递给输入框的道具。这样你就可以删除点击输入时发生的事件。

    var newProps = getInputProps();
    
    delete newProps.onMouseDown; //delete the extra MouseDown event
    
    return (
    ...
        <input
        ...
         
        placeholder="Location"
        {...newProps}  //use newProps rather than calling getInputProps
    

    当您单击它时,它将停止显示该弹出窗口。

    您可以查看工作代码here

    【讨论】:

      猜你喜欢
      • 2021-11-13
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-08
      • 2020-11-18
      相关资源
      最近更新 更多