Saltar al contenido

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:

  1. 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.
  2. 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".

Combo box

El valor debe elegirse de un conjunto predefinido de valores permitidos.

<Autocomplete
  disablePortal
  id="combo-box-demo"
  options={top100Films}
  sx={{ 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.

Selección de País

Selecciona uno de los 248 países.

Estados controlables

El componente tiene dos estados que pueden ser controlados:

  1. 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.
  2. 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.

value: 'Option 1'
inputValue: ''

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}
  sx={{ width: 300 }}
  renderInput={(params) => <TextField {...params} label="With categories" />}
/>

Deshabilitar opciones

<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, 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';

Hook personalizado

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 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.

Casillas de Verificación

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" />
  )}
/>

Tamaños

Fancy smaller inputs? Use the size prop.

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.

Selector de GitHub

Esta demo reproduce el selector de etiquetas de GitHub:

help wanted
type: bug

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

  1. config (Object [optional]):
  • config.ignoreAccents (Boolean [optional]): Por defecto a true. Elimina los acentos.
  • config.ignoreCase (Boolean [optional]): Por defecto a true. En minúsculas todo.
  • config.limit (Number [optional]): Por defecto a null. Limita el número de opciones sugeridas para ser mostrado. Por ejemplo, si config.limit es 100, sólo las primeras 100 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 a false. 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"
  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 = 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 de id="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.