#reactjs #material-ui
Вопрос:
Я создаю компонент автозаполнения в React.js с помощью материала-UI безголовый крючок для автозаполнения. Компонент работает должным образом. Когда пользователь попытается ввести какой-либо символ, Listbox
он автоматически откроется.
Codesandbox:
Код:
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 amp;amp; (
<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;
Комментарии:
1. Я только что обновил ваш код в песочнице . Пожалуйста, ознакомьтесь. Как только пользователь выбирает какое-либо значение, мы просто отключаем ввод, используя приведенный ниже код.
disabled={Boolean(value) amp;amp; !isOpen}
Хотя это отключает возможность повторного редактирования выбора после того, как пользователь выбрал какое-либо значение.2. @Junaid Автозаполнение не должно отключаться, пользователь может повторно ввести любые результаты совпадения.
Ответ №1:
Вы можете сохранить выбранный элемент в состоянии и использовать его в 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 amp;amp; 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 amp;amp; (
<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
И он перестанет показывать это всплывающее окно, когда вы нажмете на него.
Вы можете проверить рабочий код здесь