Cómo sanitizar la entrada del componente Autocomplete de MUI

En este artículo, abordaremos un problema común que se presenta al intentar sanitizar la entrada del usuario en un componente Autocomplete de MUI dentro de una aplicación React. A menudo, los desarrolladores quieren restringir la entrada a ciertos caracteres válidos, pero pueden encontrarse con que la sanitización no se aplica correctamente, especialmente en el caso de la escritura en el campo de texto.

Lo que se tiene

El objetivo es sanitizar la entrada ingresada en el componente Autocomplete para evitar que el usuario ingrese caracteres que no tienen sentido, permitiendo solo números y dos puntos.

Intentos realizados

Se ha creado un componente que incluye tanto un input nativo como un componente de Autocomplete. Se estableció un valor controlado para ambos componentes, y se implementó una función de sanitización que reemplaza cualquier carácter que no sea un número o dos puntos.

const Form = () => {
  const sanitize = value => value.replace(/[^0-9:]/g, '')
  const [value, setValue] = useState('')

  return (
    <>
      <input type="text" value={value} onChange={(e) => { setValue(sanitize(e.target.value)) }} />
      <Autocomplete
        options={['12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00']}
        value={value}
        inputValue={value}
        onChange={(_, value) => { setValue(sanitize(value || '')) }}
        freeSolo
        renderInput={(params) => (
          <TextField {...params} label="Value" value={value} onChange={(e) => {
            setValue(sanitize(e.target.value))
          }} />
        )}
      />
    </>
  )
}

Problema identificado

A pesar de que el input nativo funciona correctamente, el componente MUI no sanitiza adecuadamente la entrada del usuario. Al escribir letras en el campo, estas no se filtran de inmediato, y solo desaparecen al ingresar un número después de ellas. Esto se debe a la forma en que MUI gestiona el valor de entrada y la lógica de actualización.

Solución propuesta

Para solucionar este problema, se sugiere realizar los siguientes ajustes:

  1. Modificar el valor de inputValue en el componente Autocomplete para que use el estado ya sanitizado.
  2. Asegurarse de que la función sanitize se aplique correctamente en todos los eventos de cambio, tanto en el input como en el Autocomplete.
const Form = () => {
  const sanitize = value => value.replace(/[^0-9:]/g, '')
  const [value, setValue] = useState('')

  return (
    <>
      <input type="text" value={value} onChange={(e) => { setValue(sanitize(e.target.value)) }} />
      <Autocomplete
        options={['12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00']}
        inputValue={sanitize(value)} // aplicar la sanitización aquí
        onInputChange={(e, newValue) => { setValue(sanitize(newValue)) }} // usar onInputChange para actualizar el valor
        freeSolo
        renderInput={(params) => (
          <TextField {...params} label="Value" onChange={(e) => {
            setValue(sanitize(e.target.value))
          }} />
        )}
      />
    </>
  )
}

Con estos cambios, el componente debería comportarse como se espera, permitiendo solo caracteres válidos y actualizando la vista en tiempo real durante la escritura.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *