Skip to content

Unidad 4: Manejo de Formularios y Validaciones en el Cliente

Objetivo: Aprender a manejar formularios en aplicaciones web, validar los datos de entrada con JavaScript y Expresiones Regulares, y utilizar eventos para mejorar la experiencia del usuario.


4.1 Validaciones con JavaScript y RegExp

¿Qué vamos a aprender?

En esta sección veremos cómo validar formularios en tiempo real y al enviarlos, utilizando JavaScript y Expresiones Regulares (RegExp). Aprenderemos a validar: - Campos de texto. - Correos electrónicos. - Contraseñas seguras. - Números y valores numéricos. - Selección de opciones (checkbox, radio, select).

Ejemplo base de Formulario con Bootstrap

Formulario Completo con Todos los Tipos de Inputs

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Formulario de Registro</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="container mt-4">
    <h2>Registro de Usuario</h2>
    <form id="registro-form" class="needs-validation" novalidate>
        <div class="mb-3">
            <label class="form-label">Nombre</label>
            <input type="text" class="form-control" id="nombre" required>
            <div class="invalid-feedback">El nombre debe tener al menos 3 caracteres.</div>
        </div>
        <div class="mb-3">
            <label class="form-label">Email</label>
            <input type="email" class="form-control" id="email" required>
            <div class="invalid-feedback">Correo electrónico inválido.</div>
        </div>
        <div class="mb-3">
            <label class="form-label">Contraseña</label>
            <input type="password" class="form-control" id="password" required>
            <div class="invalid-feedback">Debe contener al menos 6 caracteres.</div>
        </div>
        <div class="mb-3">
            <label class="form-label">Edad</label>
            <input type="number" class="form-control" id="edad" required>
            <div class="invalid-feedback">Debes ser mayor de 18 años.</div>
        </div>
        <div class="mb-3">
            <label class="form-label">Género</label>
            <select id="genero" class="form-select" required>
                <option value="">Seleccione...</option>
                <option value="masculino">Masculino</option>
                <option value="femenino">Femenino</option>
            </select>
            <div class="invalid-feedback">Debes seleccionar un género.</div>
        </div>
        <div class="mb-3 form-check">
            <input type="checkbox" class="form-check-input" id="terminos" required>
            <label class="form-check-label">Acepto los términos</label>
            <div class="invalid-feedback">Debes aceptar los términos.</div>
        </div>
        <button type="submit" class="btn btn-primary">Registrarse</button>
    </form>

    <script src="validaciones.js"></script>
</body>
</html>
Este formulario incluye validaciones de texto, email, contraseña, números y selección de opciones con Bootstrap.


4.2 Manejo de eventos en formularios (change, blur, submit)

Validaciones con Eventos

Validaciones con change y blur

document.querySelectorAll("input, select").forEach(elemento => {
    elemento.addEventListener("blur", validarCampo);
    elemento.addEventListener("change", validarCampo);
});

function validarCampo(event) {
    let campo = event.target;
    if (campo.value.trim() === "") {
        campo.classList.add("is-invalid");
    } else {
        campo.classList.remove("is-invalid");
        campo.classList.add("is-valid");
    }
}
Explicación: - Se valida cada campo cuando pierde el foco (blur) o cambia (change). - Se aplica la clase is-invalid de Bootstrap para mostrar el error visualmente.

Ejemplo de Precarga de Datos desde un Servidor

Rellenado Automático de Formulario con Datos del Servidor

1
2
3
4
5
6
7
8
9
async function cargarDatos() {
    let response = await fetch("https://jsonplaceholder.typicode.com/users/1");
    let usuario = await response.json();
    document.getElementById("nombre").value = usuario.name;
    document.getElementById("email").value = usuario.email;
    document.getElementById("edad").value = 30;
    document.getElementById("genero").value = "masculino";
}
document.addEventListener("DOMContentLoaded", cargarDatos);
Explicación: - Se obtiene un usuario de la API y se rellenan los campos con su información.


Ejercicios

Práctica con Validaciones y Precarga de Datos

  1. Modifica la validación para que si el usuario escribe menos de 6 caracteres en la contraseña, también se muestre un mensaje de error.
  2. Usa fetch() para obtener más datos de un usuario y completar los campos del formulario con ellos.
Solución
function validarCampo(event) {
    let campo = event.target;
    if (campo.id === "password" && campo.value.length < 6) {
        campo.classList.add("is-invalid");
    } else {
        campo.classList.remove("is-invalid");
        campo.classList.add("is-valid");
    }
}

async function cargarDatos() {
    let response = await fetch("https://jsonplaceholder.typicode.com/users/2");
    let usuario = await response.json();
    document.getElementById("nombre").value = usuario.name;
    document.getElementById("email").value = usuario.email;
}
document.addEventListener("DOMContentLoaded", cargarDatos);

4.3 Proyecto Final: Formulario Completo con Validaciones y API Externa

Objetivo

Construir un formulario de registro completo que valide los datos en tiempo real y al enviarlo, asegurando que todos los campos sean correctos antes de permitir el envío. Además, utilizaremos una API externa para precargar datos y enviar los datos registrados a un servidor.

Requisitos

Validar cada campo del formulario en tiempo real y al enviarlo.
Mostrar mensajes de error debajo de cada campo cuando sea inválido usando Bootstrap.
Evitar el envío si hay errores.
Precargar datos desde una API externa simulando una modificación de datos.
Enviar los datos a una API externa usando fetch() con POST.


Estructura del HTML para el Formulario

Formulario con Bootstrap y API

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Registro de Usuario</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="container mt-4">
    <h2>Registro de Usuario</h2>
    <form id="registro-form" class="needs-validation" novalidate>
        <div class="mb-3">
            <label class="form-label">Nombre</label>
            <input type="text" class="form-control" id="nombre" required>
            <div class="invalid-feedback">El nombre debe tener al menos 3 caracteres.</div>
        </div>
        <div class="mb-3">
            <label class="form-label">Email</label>
            <input type="email" class="form-control" id="email" required>
            <div class="invalid-feedback">Correo electrónico inválido.</div>
        </div>
        <div class="mb-3">
            <label class="form-label">Contraseña</label>
            <input type="password" class="form-control" id="password" required>
            <div class="invalid-feedback">Debe contener al menos 6 caracteres.</div>
        </div>
        <button type="submit" class="btn btn-primary">Registrarse</button>
    </form>
    <script src="validaciones.js"></script>
</body>
</html>

Solución del validaciones.js con API Externa

Código completo de validaciones.js

document.addEventListener("DOMContentLoaded", () => {
    precargarDatos();
    document.querySelectorAll("input").forEach(input => {
        input.addEventListener("blur", validarCampo);
        input.addEventListener("input", validarCampo);
    });
    document.getElementById("registro-form").addEventListener("submit", enviarDatos);
});

async function precargarDatos() {
    try {
        let response = await fetch("https://jsonplaceholder.typicode.com/users/1");
        let usuario = await response.json();
        document.getElementById("nombre").value = usuario.name;
        document.getElementById("email").value = usuario.email;
    } catch (error) {
        console.error("Error al precargar datos", error);
    }
}

function validarCampo(event) {
    let campo = event.target;
    if (campo.id === "nombre" && campo.value.length < 3) {
        campo.classList.add("is-invalid");
    } else if (campo.id === "email" && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(campo.value)) {
        campo.classList.add("is-invalid");
    } else if (campo.id === "password" && campo.value.length < 6) {
        campo.classList.add("is-invalid");
    } else {
        campo.classList.remove("is-invalid");
        campo.classList.add("is-valid");
    }
}

async function enviarDatos(event) {
    event.preventDefault();
    let formulario = document.getElementById("registro-form");
    if (!formulario.checkValidity()) {
        formulario.classList.add("was-validated");
        return;
    }

    let usuario = {
        nombre: document.getElementById("nombre").value,
        email: document.getElementById("email").value,
        password: document.getElementById("password").value
    };

    try {
        let response = await fetch("https://jsonplaceholder.typicode.com/posts", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(usuario)
        });
        let data = await response.json();
        alert("Registro exitoso: " + JSON.stringify(data));
    } catch (error) {
        console.error("Error al enviar datos", error);
    }
}

Explicación:

  • precargarDatos(): Obtiene datos simulados de un usuario desde la API y los carga en el formulario.
  • validarCampo(): Valida los campos en tiempo real y aplica estilos de Bootstrap.
  • enviarDatos(): Captura los datos del formulario y los envía a la API con POST.