Validando un campo numérico con yup, utilizando un mensaje personalizado y verificando si el campo está vacío.
Estoy validando un campo que solo puede aceptar un número decimal positivo.
Mi esquema de Yup se ve de la siguiente manera:
yup.object().shape({
Duración: yup
.number()
.typeError(‘Ingrese una duración. El campo no puede quedar en blanco.’)
.positive(‘Debe ser un número positivo.’),
})
Como resultado,
- Cuando el usuario ingrese un número negativo (incluyendo 0), se mostrará el mensaje ‘Debe ser un número positivo’.
- Cuando el usuario deje el campo en blanco, se mostrará el mensaje ‘Ingrese una duración. El campo no puede quedar en blanco’.
- Sin embargo, cuando el usuario ingrese una cadena como ‘dos minutos’ u otra cadena, se mostrará el mensaje ‘Ingrese una duración. El campo no puede quedar en blanco’, lo cual no tiene sentido.
Podría cambiar el mensaje de typeError() por algo más genérico, pero me preguntaba si había una forma más completa de manejar el escenario.
Entonces, cuando el usuario ingrese
- una cadena, puedo mostrar el mensaje ‘Debe ser un tipo de número’ y,
- cuando el campo se deja en blanco, puedo mostrar el mensaje ‘Ingrese una duración. El campo no puede quedar en blanco’.
davy.ai
Para lograr esto, puedes modificar el esquema Yup para incluir el método
test()
y crear una regla de validación personalizada. Aquí tienes un ejemplo de implementación:En este esquema actualizado:
typeError()
se ha actualizado para ser más genérico, ya que también se utilizará para cadenas de texto y otros tipos de entrada no numéricas.test()
verifica si la entrada es un número decimal utilizando una expresión regular (/^\d*\.?\d+$/
). Si no lo es, se mostrará el mensaje de validación'Debe ser un número decimal.'
.test()
también verifica si el campo es opcional devolviendotrue
si el valor es una cadena de texto vacía (''
).Al incluir esta regla de validación personalizada, el usuario ahora recibirá mensajes de error más específicos para los diferentes escenarios: número negativo, entrada no decimal y campo en blanco.