Autocompletado
El autocompletado es una caja de texto normal mejorada por un panel de opciones sugeridas.
El widget es útil para establecer el valor de un cuadro de texto de una sola línea en uno de los dos tipos de escenarios:
- El valor para el cuadro de texto debe elegirse de un conjunto predefinido de valores permitidos, por ejemplo, un campo de ubicación debe contener un nombre de ubicación válido: cuadro combinado.
- El cuadro de texto puede contener cualquier valor arbitrario, pero es de gran ventaja sugerir posibles valores al usuario, por ejemplo, un campo de búsqueda puede sugerir búsquedas similares o anteriores para ahorrarle tiempo al usuario: solo libre.
Esto pretende ser una versión mejorada de los paquetes "react-select" y "downshift".
<Autocomplete
disablePortal
id="combo-box-demo"
options={top100Films}
style={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Movie" />}
/>
Campo de pruebas
Por defecto, el componente acepta la siguiente estructura de opciones:
const filterOptions = createFilterOptions({
matchFrom: 'start',
stringify: option => option.title,
});
<Autocomplete filterOptions={filterOptions} />
por ejemplo:
const options = [
{ label: 'The Godfather', id: 1 },
{ label: 'Pulp Fiction', id: 2 },
];
// or
const options = ['The Godfather', 'Pulp Fiction'];
However, you can use different structures by providing a getOptionLabel
prop.
Campo de pruebas
Cada uno de los siguientes ejemplos demuestran una característica del componente Autocompletado.
Estados controlables
El componente tiene dos estados que pueden ser controlados:
- el "valor" del estado con la combinación de props
value
/onChange
. Este estado representa el valor seleccionado por el usuario, por ejemplo al pulsar Enter. - el estado "valor de entrada" con la combinación de props
inputValue
/onInputChange
. Este estado representa el valor mostrado en el campo de texto.
⚠️ Estos dos estados son aislados, deben ser controlados de forma independiente.
Free solo
Setear freeSolo
a true, para que el cuadro de texto pueda contener cualquier valor arbitrario.
Campo de búsqueda
También puedes mostrar un diálogo cuando el usuario quiere añadir un nuevo valor.
Creable
Si pretendes usar este modo para una experiencia similar a un combo box (una versión mejora de un selector de elementos) te recomendamos configurar:
selectOnFocus
que ayuda al usuario a borrar el valor seleccionado.clearOnBlur
que ayuda a que el usuario introduzca un nuevo valor.handleHomeEndKeys
para mover el foco dentro de la ventana emergente con las claves Home y End.- Una última opción, por ejemplo
Agregar "SU BÚSQUEDA"
.
También puedes mostrar un diálogo cuando el usuario quiere añadir un nuevo valor.
Agrupado
Puedes agrupar las opciones con el accesorio groupBy
. Si lo haces, asegúrate de que las opciones también están ordenadas con la misma dimensión con la que están agrupadas, de lo contrario se crearan cabeceras duplicadas.
<Autocomplete
id="grouped-demo"
options={options.sort((a, b) => -b.firstLetter.localeCompare(a.firstLetter))}
groupBy={(option) => option.firstLetter}
getOptionLabel={(option) => option.title}
style={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="With categories" />}
/>
<Autocomplete
id="disabled-options-demo"
options={timeSlots}
getOptionDisabled={(option) =>
option === timeSlots[0] || option === timeSlots[2]
}
style={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Disabled options" />}
/>
useAutocomplete
For advanced customization use cases, we expose a headless useAutocomplete()
hook. Acepta casi las mismas opciones que el componente Autocompletar menus las propiedades relacionadas al renderizado de JSX. El componente Autocompletar usa este hook internamente.
importar useAutocomplete de '@material-ui/core/useAutocomplete';
También conocidos como etiquetas, el usuario puede introducir más de un valor.
Peticiones asíncronas
The component supports two different asynchronous use-cases:
- 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.
Load on open
It displays a progress state as long as the network request is pending.
Search as you type
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} />
Lugar de Google Maps
Una interfaz de usuario personalizado para el autocompletar de Google Maps Places.
Para esta demostración, tenemos que cargar la API de Google Maps JavaScript.
⚠️ Antes de empezar a usar la API de Google Maps JavaScript, debes registrarte y crear una cuenta de facturación.
Valores múltiples
También conocidos como etiquetas, el usuario puede introducir más de un valor.
Opciones fijas
En caso de que necesites bloquear ciertas etiquetas de modo que no puedan ser removidas en la interfaz, se puede deshabilitar los chips.
Limitar las etiquetas
Puedes utilizar la propiedad limitTags
para limitar el número de opciones que aparecen cuando no se selecciona.
<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" />
)}
/>
Personalización
Input personalizado
El apoyo renderInput
te permite personalizar la entrada renderizada. El primer argumento de este apoyo renderizado contiene apoyos que necesitas para avanzar. Ponga atención específica a las claves red
y inputProps
.
Dirígete a la sección de Hook personalizado para un ejemplo de personalización con el hook useAutocomplete
en lugar del componente.
Destacados
La siguiente demostración se basa en autosuggest-highlight, una pequeña utilidad (1 kB) para resaltar texto en componentes de autosuggest y autocompletar.
Filtro personalizado
El componente expone una factoría para crear un método de filtrado para proveer a la propiedad filterOptions
. Puede usarse para cambiar el comportamiento de filtrado por defecto.
import { createFilterOptions } from '@material-ui/core/Autocomplete';
createFilterOptions(config) => filterOptions
Argumentos
config
(Object [optional]):
config.ignoreAccents
(Boolean [optional]): Por defecto atrue
. Elimina los acentos.config.ignoreCase
(Boolean [optional]): Por defecto atrue
. En minúsculas todo.config.limit
(Number [optional]): Por defecto a null. Limita el número de opciones sugeridas para ser mostrado. Por ejemplo, siconfig.limit
es100
, sólo las primeras100
coincidencias se muestran. Esto puede ser útil si existe muchas coincidencias y la virtualización no estaba establecida.config.matchFrom
('any' | 'start' [optional]): Por defecto a'any'
.config.stringify
(Func [optional]): Controla cómo una opción se convierte en una cadena, de manera que se pueden combinar en contra de la entrada de texto del fragmento.config.trim
(Boolean [optional]): Por defecto afalse
. Eliminar espacios en blanco.
Regresa
filterOptions
: método de filtro devuelto puede ser provisto directamente a la propiedad filterOptions
del componente Autocompletar
, o el parámetro del mismo nombre para el hook.
En la siguiente demostración, las opciones que se necesitan para iniciar con la consulta prefijo:
const filterOptions = createFilterOptions({
matchFrom: 'start',
stringify: (option) => option.title,
});
<Autocomplete filterOptions={filterOptions} />;
Avanzado
Para mecanismos de filtrado más completos, como la coincidencia aproximada, se recomienda buscar en match-sorter de. Por ejemplo:
import matchSorter from 'match-sorter';
const filterOptions = (options, { inputValue }) => matchSorter(options, inputValue);
<Autocomplete filterOptions={filterOptions} />;
Virtualización
Buscar entre 10.000 opciones generadas al azar. La lista está virtualizada gracias a react-window.
<Autocomplete
id="virtualize-demo"
style={{ width: 300 }}
disableListWrap
classes={classes}
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 = false;
// your handler code
}
}}
/>
Limitaciones
autocompletar/autorellenar
Los navegadores tienen heurísticos para ayudar a los usuarios a rellenar el formulario. Sin embargo, puede dañar la experiencia de usuario del componente.
By default, the component disables the 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). En el caso de que desees evitar el autorellenar, puedes intentar lo siguiente:
Nombra la entrada sin filtrar ninguna información que el navegador pueda utilizar. p.e.
id="field1"
en vez deid="country"
. Si dejas el id de vacío, el componente utiliza un identificador aleatorio.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 en iOS Safari no soporta el atributo aria-owns
especialmente bien. Puedes solucionar el problema con la propiedad disablePortal
.
ListboxComponent
Si proporciona un apoyo personalizado ListboxComponent
, usted necesita asegurarse de que el contedenedor de desplazamiento destinado tiene el atributo role
esta configurado listbox
. Esto asegura el comportamiento correcto del desplazamiento, por ejemplo cuando usas el teclado para navegar.
Accesibilidad
(WAI-ARIA: https://www.w3.org/TR/wai-aria-practices/#combobox)
Animamos el uso de una etiqueta para el cuadro de texto. El componente implementa las prácticas de creación de WAI-ARIA.