Artículo actualizado en mayo de 2026. La versión original data de 1998 y presentaba un validador JavaScript basado en convenciones de nombre de campo. Esta revisión lo conserva como referencia histórica y añade las técnicas actuales: validación HTML5 nativa y la Constraint Validation API.
El validador original de 1998: convenciones de nombre
El código que publicamos en 1998, obra de Enric Cappellani con pequeñas modificaciones de Daniel Rodríguez, resolvía la validación de formularios con un truco ingenioso: el tipo de cada campo quedaba codificado en las dos primeras letras de su atributo name. La primera letra indicaba el tipo (s para texto, n para numérico, e para email) y la segunda si era obligatorio (r) u opcional (o). Un campo llamado srNombre era, por tanto, una cadena obligatoria; noEdad, un número opcional.
Con esas reglas, una sola función Verifica() recorría todos los campos del formulario sin que el desarrollador tuviera que escribir ninguna lógica específica para cada uno. Para la época era una solución elegante: no existía nada parecido a HTML5, y la validación del lado del cliente era siempre código manual.
Puedes ver el código completo en la versión original del artículo para consulta histórica.
Validación nativa con HTML5: sin una línea de JavaScript
Desde HTML5, los navegadores validan campos de forma automática si se usan los atributos correctos. El usuario ve mensajes de error localizados sin que el desarrollador escriba nada de JavaScript:
<form> <!-- Texto obligatorio --> <input type="text" name="nombre" required placeholder="Nombre"> <!-- Email con validación de formato --> <input type="email" name="correo" required placeholder="[email protected]"> <!-- Número con rango --> <input type="number" name="edad" min="18" max="120" required> <!-- Texto con patrón personalizado: solo letras --> <input type="text" name="usuario" pattern="[A-Za-z]{3,20}" title="Solo letras, entre 3 y 20 caracteres" required> <!-- URL válida --> <input type="url" name="web" placeholder="https://..."> <!-- Teléfono con patrón --> <input type="tel" name="telefono" pattern="[0-9]{9}" title="Introduce 9 dígitos" placeholder="600000000"> <button type="submit">Enviar</button> </form>
Los atributos más útiles son:
Atributo | Propósito |
| El campo no puede quedar vacío. |
| Valida el formato de dirección de correo. |
| Valida que el valor sea una URL con protocolo. |
| Solo acepta dígitos; admite |
| Expresión regular que debe cumplir el valor. |
| Longitud mínima y máxima del texto. |
| Mensaje de ayuda que el navegador muestra cuando falla el |
La Constraint Validation API: JavaScript moderno para mensajes personalizados
La validación nativa de HTML5 muestra mensajes en el idioma del sistema operativo, no siempre en español, y el estilo visual lo controla el navegador. Para personalizar ambas cosas existe la Constraint Validation API, que expone el estado de validación de cada campo como propiedades JavaScript:
const form = document.querySelector('form');
const email = document.querySelector('#correo');
email.addEventListener('input', () => {
if (email.validity.valueMissing) {
email.setCustomValidity('El correo electrónico es obligatorio.');
} else if (email.validity.typeMismatch) {
email.setCustomValidity('Introduce una dirección de correo válida.');
} else {
email.setCustomValidity(''); // vacío = válido
}
});
form.addEventListener('submit', (e) => {
if (!form.checkValidity()) {
e.preventDefault();
form.reportValidity(); // muestra los mensajes de error
}
});
Las propiedades de validity más habituales son:
Propiedad | Cuándo es |
| El campo tiene |
| El valor no respeta el formato del |
| El valor no cumple el |
| El valor es más corto que |
| El número es menor que |
| El número es mayor que |
| El campo pasa todas las restricciones. |
Ejemplo completo con mensajes en español
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Formulario con validación</title>
<style>
input:invalid { border: 2px solid #e74c3c; }
input:valid { border: 2px solid #2ecc71; }
.error { color: #e74c3c; font-size: 0.85em; }
</style>
</head>
<body>
<form id="miForm" novalidate>
<div>
<label for="nombre">Nombre *</label>
<input id="nombre" type="text" required minlength="2">
<span class="error" id="err-nombre"></span>
</div>
<div>
<label for="correo">Email *</label>
<input id="correo" type="email" required>
<span class="error" id="err-correo"></span>
</div>
<button type="submit">Enviar</button>
</form>
<script>
const mensajes = {
nombre: {
valueMissing: 'El nombre es obligatorio.',
tooShort: 'El nombre debe tener al menos 2 caracteres.',
},
correo: {
valueMissing: 'El correo es obligatorio.',
typeMismatch: 'Introduce un correo válido (ej: [email protected]).',
},
};
function validarCampo(campo) {
const v = campo.validity;
const id = campo.id;
const span = document.getElementById('err-' + id);
const msgs = mensajes[id] || {};
let msg = '';
for (const [clave, texto] of Object.entries(msgs)) {
if (v[clave]) { msg = texto; break; }
}
span.textContent = msg;
campo.setCustomValidity(msg);
}
document.querySelectorAll('input').forEach(campo => {
campo.addEventListener('blur', () => validarCampo(campo));
});
document.getElementById('miForm').addEventListener('submit', e => {
e.preventDefault();
document.querySelectorAll('input').forEach(validarCampo);
if (document.getElementById('miForm').checkValidity()) {
alert('Formulario enviado correctamente.');
}
});
</script>
</body>
</html>
Para proyectos con frameworks: Zod y Yup
En aplicaciones React, Vue o Angular la validación de formularios suele delegarse a librerías especializadas. Las dos más extendidas son Zod (con inferencia de tipos TypeScript integrada) y Yup (esquemas declarativos compatibles con Formik y React Hook Form). Ambas permiten definir las reglas como objetos JavaScript y obtener mensajes de error estructurados sin tocar el DOM directamente.
Para profundizar en JavaScript moderno y entender el contexto en el que encaja esta API, el artículo JavaScript: el lenguaje que impulsó la web moderna ofrece una visión completa de su evolución. Y si trabajas con jQuery en proyectos existentes, jQuery 4.0 introduce cambios que afectan a los plugins de validación más populares de ese ecosistema.
Imagen: Pexels / Pixabay
