Autocomplete (Автодополнение)
Автодополнение - это обычный ввод текста, дополненный панелью предлагаемых опций.
Этот виджет используется для установки значения однострочного текстового поля. Он полезен в одном из двух случев:
- Значение для текстового поля должно быть выбрано из предопределенного набора допустимых значений, например, поле местоположения должно содержать действительное имя местоположения: поле со списком.
- Текстовое поле может содержать любое произвольное значение, но целесообразно предлагать пользователю возможные значения. Например, поле поиска может предлагать аналогичные или предыдущие поиски, чтобы сэкономить время пользователя: free solo.
It's meant to be an improved version of the "react-select" and "downshift" packages.
<Autocomplete
disablePortal
id="combo-box-demo"
options={top100Films}
sx={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Movie" />}
/>
Песочница
По умолчанию, компонент принимает следующую структуру параметров:
const filterOptions = createFilterOptions({
matchFrom: 'start',
stringify: option => option.title,
});
<Autocomplete filterOptions={filterOptions} />
Например:
const options = [
{ label: 'The Godfather', id: 1 },
{ label: 'Pulp Fiction', id: 2 },
];
// or
const options = ['The Godfather', 'Pulp Fiction'];
Но, можно использовать разные структуры, добавив getOptionLabel
.
Песочница
Each of the following examples demonstrates one feature of the Autocomplete component.
Controlled states
The component has two states that can be controlled:
- the "value" state with the
value
/onChange
props combination. Это состояние показывает значение, выбранное пользователем, для instance объекта при нажатии Enter. - the "input value" state with the
inputValue
/onInputChange
props combination. This state represents the value displayed in the textbox.
⚠️ These two states are isolated, they should be controlled independently.
Произвольное значение
Установите для freeSolo
значение true, чтобы текстовое поле могло содержать любое произвольное значение.
Ввод для поиска
Вы также можете показать диалоговое окно, если пользователь хочет добавить новое значение.
Создаваемый
If you intend to use this mode for a combo box like experience (an enhanced version of a select element) we recommend setting:
selectOnFocus
to helps the user clear the selected value.clearOnBlur
to helps the user to enter a new value.handleHomeEndKeys
, чтобы переместить фокус внутри всплывающего окна с помощью клавиш Home и End.- A last option, for instance
Add "YOUR SEARCH"
.
Вы также можете показать диалоговое окно, если пользователь хочет добавить новое значение.
Сгруппированные
Вы можете сгруппировать параметры с помощью groupBy
. Если вы это сделаете, убедитесь, что параметры также сортируются с одинаковым размером, который они сгруппированы, в противном случае будут повторяющиеся заголовки.
<Autocomplete
id="grouped-demo"
options={options.sort((a, b) => -b.firstLetter.localeCompare(a.firstLetter))}
groupBy={(option) => option.firstLetter}
getOptionLabel={(option) => option.title}
sx={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="With categories" />}
/>
<Autocomplete
id="disabled-options-demo"
options={timeSlots}
getOptionDisabled={(option) =>
option === timeSlots[0] || option === timeSlots[2]
}
sx={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Disabled options" />}
/>
useAutocomplete
For advanced customization use cases, a headless useAutocomplete()
hook is exposed. It accepts almost the same options as the Autocomplete component minus all the props related to the rendering of JSX. The Autocomplete component is built on this hook.
import useAutocomplete from '@material-ui/core/useAutocomplete';
- 4.5 4,5 кБ в сжатом виде.
Head to the Customized Autocomplete section for a customization example with the Autocomplete
component instead of the hook.
Асинхронные запросы
Компонент поддерживает два асинхронных варианта использования:
- Load on open: it waits for the component to be interacted with to load the options.
- Search as you type: a new request is made for each keystroke.
Загрузить на открытие
Он отображает состояние прогресса до тех пор, пока запрос находится в ожидании (pending).
Поиск при вводе
If your logic is fetching new options on each keystroke and using the current value of the textbox to filter on the server, you may want to consider throttling requests.
Additionally, you will need to disable the built-in filtering of the Autocomplete
component by overriding the filterOptions
prop:
import matchSorter from 'match-sorter';
const filterOptions = (options, { inputValue }) =>
matchSorter(options, inputValue);
<Autocomplete filterOptions={filterOptions} />
Места Google Maps
A customized UI for Google Maps Places Autocomplete.
For this demo, we need to load the Google Maps JavaScript API.
⚠️ Перед началом использования API карт Google, JavaScript необходимо зарегистрировать и создать учетную запись для выставления счетов.
Множественные значения
Also known as tags, the user is allowed to enter more than one value.
Фиксированные опции
В случае, если вам нужно зафиксировать определенный тег (так что он не мог быть удалён через интерфейс), вы можете установить chips в состояние disabled.
<Autocomplete
multiple
limitTags={2}
id="multiple-limit-tags"
options={top100Films}
getOptionLabel={(option) => option.title}
defaultValue={[top100Films[13], top100Films[12], top100Films[11]]}
renderInput={(params) => (
<TextField {...params} label="limitTags" placeholder="Favorites" />
)}
/>
Кастомизация
Custom input
The renderInput
prop allows you to customize the rendered input. The first argument of this render prop contains props that you need to forward. Pay specific attention to the ref
and inputProps
keys.
Перейдите в секцию Кастомизированный хук для примера кастомизации хука useAutocomplete
вместо компонента
Основные моменты
The following demo relies on autosuggest-highlight, a small (1 kB) utility for highlighting text in autosuggest and autocomplete components.
Пользовательский фильтр
The component exposes a factory to create a filter method that can provided to the filterOptions
prop. You can use it to change the default option filter behavior.
import { createFilterOptions } from '@material-ui/core/Autocomplete';
createFilterOptions(config) => filterOptions
Аргументы
config
(object [optional]):
config.ignoreAccents
(bool [optional]): Defaults totrue
. Remove diacritics.config.ignoreCase
(bool [optional]): Defaults totrue
. Lowercase everything.config.limit
(number [optional]): Default to null. Limit the number of suggested options to be shown. For example, ifconfig.limit
is100
, only the first100
matching options are shown. It can be useful if a lot of options match and virtualization wasn't set up.config.matchFrom
('any' | 'start' [optional]): Defaults to'any'
.config.stringify
(func [optional]): Controls how an option is converted into a string so that it can be matched against the input text fragment.config.trim
(bool [optional]): Defaults tofalse
. Remove trailing spaces.
Возвращает
filterOptions
: the returned filter method can be provided directly to the filterOptions
prop of the Autocomplete
component, or the parameter of the same name for the hook.
In the following demo, the options need to start with the query prefix:
const filterOptions = createFilterOptions({
matchFrom: 'start',
stringify: (option) => option.title,
});
<Autocomplete filterOptions={filterOptions} />;
Дополнительные параметры
For richer filtering mechanisms, like fuzzy matching, it's recommended to look at match-sorter. Например:
import matchSorter from 'match-sorter';
const filterOptions = (options, { inputValue }) => matchSorter(options, inputValue);
<Autocomplete filterOptions={filterOptions} />;
Виртуализация
Поиск в 10000 случайно сгенерированных опций. Список виртуализирован благодаря реагирующему окну.
<Autocomplete
id="virtualize-demo"
sx={{ width: 300 }}
disableListWrap
PopperComponent={StyledPopper}
ListboxComponent={ListboxComponent}
renderGroup={renderGroup}
options={OPTIONS}
groupBy={(option) => option[0].toUpperCase()}
renderInput={(params) => <TextField {...params} label="10,000 options" />}
renderOption={(props, option) => (
<li {...props}>
<Typography noWrap>{option}</Typography>
</li>
)}
/>
Events
If you would like to prevent the default key handler behavior, you can set the event's defaultMuiPrevented
property to true
:
<Autocomplete
onKeyDown={(event) => {
if (event.key === 'Enter') {
// Prevent's default 'Enter' behavior.
event.defaultMuiPrevented = true;
// your handler code
}
}}
/>
Ограничения
Автозаполнение
Browsers have heuristics to help the user fill in form inputs. However, this can harm the UX of the component.
By default, the component disables the input autocomplete feature (remembering what the user has typed for a given field in a previous session) with the autoComplete="off"
attribute. Google Chrome does not currently support this attribute setting (Issue 587466). A possible workaround is to remove the id
to have the component generate a random one.
In addition to remembering past entered values, the browser might also propose autofill suggestions (saved login, address, or payment details). In the event you want the avoid autofill, you can try the following:
Name the input without leaking any information the browser can use. e.g.
id="field1"
instead ofid="country"
. If you leave the id empty, the component uses a random id.Set
autoComplete="new-password"
(some browsers will suggest a strong password for inputs with this attribute setting):<TextField {...params} inputProps={{ ...params.inputProps, autoComplete: 'new-password', }} />
Read the guide on MDN for more details.
iOS VoiceOver
VoiceOver on iOS Safari doesn't support the aria-owns
attribute very well. You can work around the issue with the disablePortal
prop.
ListboxComponent
If you provide a custom ListboxComponent
prop, you need to make sure that the intended scroll container has the role
attribute set to listbox
. This ensures the correct behavior of the scroll, for example when using the keyboard to navigate.
Доступность
(WAI-ARIA: https://www.w3.org/TR/wai-aria-practices/#combobox)
We encourage the usage of a label for the textbox. The component implements the WAI-ARIA authoring practices.