Formularios con JavaScript

Los formularios son la forma en que la persona da datos a una web: buscar, filtrar, personalizar, escribir un mensaje.

.value (texto), .valueAsNumber, .checked para leer campos.

input para reaccionar en vivo; submit en el formulario con preventDefault().

Variables CSS + setProperty = personalización en tiempo real.

Valida primero con HTML (required, type, pattern) y usa JavaScript para mensajes claros, junto al campo y accesibles.

  • Los formularios son la forma en que la persona da datos a una web: buscar, filtrar, personalizar, escribir un mensaje. En la lección Formularios y tablas los maquetaste; ahora vas a leer sus valores, reaccionar mientras se escribe y validarlos con mensajes claros.
  • <label for="nombre">Nombre</label> <input id="nombre" type="text">
  • const campoNombre = document.querySelector("#nombre"); console.log(campoNombre.value); // lo que haya escrito (siempre texto)
  • CampoQué leerOjo input de texto, textarea, select.valueSiempre es texto input type="number" o range.valueAsNumber o Number(.value)Para hacer cuentas input type="checkbox".checkedtrue o false input type="color".valueUn color en hexadecimal: "#e63946" Grupo de radiodocument.querySelector('input[name="talla"]:checked').valueSolo el marcado
  • El evento input se dispara con cada cambio: cada letra, cada movimiento del slider. Es el que da la sensación de "tiempo real".

Introducción

Los formularios son la forma en que la persona da datos a una web: buscar, filtrar, personalizar, escribir un mensaje. En la lección Formularios y tablas los maquetaste; ahora vas a leer sus valores, reaccionar mientras se escribe y validarlos con mensajes claros.

Leer el valor de un campo

<label for="nombre">Nombre</label> <input id="nombre" type="text">

const campoNombre = document.querySelector("#nombre"); console.log(campoNombre.value); // lo que haya escrito (siempre texto)

CampoQué leerOjo input de texto, textarea, select.valueSiempre es texto input type="number" o range.valueAsNumber o Number(.value)Para hacer cuentas input type="checkbox".checkedtrue o false input type="color".valueUn color en hexadecimal: "#e63946" Grupo de radiodocument.querySelector('input[name="talla"]:checked').valueSolo el marcado

Reaccionar mientras se escribe: el evento input

El evento input se dispara con cada cambio: cada letra, cada movimiento del slider. Es el que da la sensación de "tiempo real".

<label for="texto">Tu frase</label> <textarea id="texto" maxlength="140"></textarea> <p id="contador" aria-live="polite">0 / 140</p>

const texto = document.querySelector("#texto"); const contador = document.querySelector("#contador"); texto.addEventListener("input", () => { contador.textContent = `${texto.value.length} / 140`; });

aria-live="polite" hace que los lectores de pantalla lean el cambio cuando la persona deja de escribir.

Un personalizador visual con variables CSS

Combinando input con setProperty (lección El DOM) controlas el diseño en vivo:

<label for="color">Color de marca</label> <input id="color" type="color" value="#2a9d8f"> <label for="radio">Esquinas: <output id="radio-valor">8</output> px</label> <input id="radio" type="range" min="0" max="40" value="8">

const raiz = document.documentElement; const color = document.querySelector("#color"); const radio = document.querySelector("#radio"); const radioValor = document.querySelector("#radio-valor"); color.addEventListener("input", () => { raiz.style.setProperty("--color-marca", color.value); }); radio.addEventListener("input", () => { raiz.style.setProperty("--radio", `${radio.value}px`); radioValor.textContent = radio.value; });

:root { --color-marca: #2a9d8f; --radio: 8px; } .tarjeta { border: 3px solid var(--color-marca); border-radius: var(--radio); }

Enviar un formulario: el evento submit

Escucha el submit del formulario, no el click del botón: así también funciona al pulsar Intro.

const formulario = document.querySelector("#contacto"); formulario.addEventListener("submit", (evento) => { evento.preventDefault(); // no recargar la página const datos = new FormData(formulario); console.log(datos.get("correo")); // lee cada campo por su atributo name });

FormData recoge todos los campos que tengan atributo name.

Validar: primero HTML, después JavaScript

HTML ya valida mucho sin JavaScript. Úsalo siempre primero:

<input id="correo" name="correo" type="email" required> <input id="cp" name="cp" inputmode="numeric" pattern="[0-9]{5}" required>

required: obligatorio. type="email", type="url", type="number" con min y max: formato. pattern: una expresión regular (aquí, cinco cifras). minlength y maxlength: longitud del texto.

El navegador no deja enviar el formulario si algo no cumple y muestra su propio aviso. Con CSS puedes marcar los campos con :user-invalid (solo después de que la persona los haya tocado):

Buenas prácticas en los mensajes

Di qué pasa y cómo arreglarlo: "El código postal tiene 5 cifras", no "Error". Muestra el mensaje junto al campo, no solo en un color rojo (hay quien no distingue el rojo). No valides mientras la persona empieza a escribir un campo vacío: espera a que salga del campo o use :user-invalid. Nunca borres lo que ya ha escrito.

Practica

Un contador de caracteres para una biografía de 160 caracteres que cambia a color de aviso a partir de 140. Una tarjeta con un selector de color y un slider de tamaño de texto que cambian dos variables CSS y muestran su valor. Un formulario de suscripción con correo obligatorio: si al enviarlo es válido, sustituye el formulario por un mensaje de "Gracias"; si no, muestra el mensaje junto al campo.

Errores frecuentes

Hacer cuentas con .value sin convertirlo: "10" + 5 da "105". Olvidar las unidades al pasar un número a una variable CSS de medida. Escuchar click en el botón de enviar en lugar de submit en el formulario. Olvidar evento.preventDefault() y ver que la página se recarga. Mensajes de error solo en color o sin relación con el campo (aria-describedby). Usar change cuando quieres respuesta inmediata en un slider (es input).

JavaScript
70

Formularios con JavaScript

Los formularios son la forma en que la persona da datos a una web: buscar, filtrar, personalizar, escribir un mensaje.

Código del tema: event.preventDefault()

📘 Teoría

Introducción

Los formularios son la forma en que la persona da datos a una web: buscar, filtrar, personalizar, escribir un mensaje. En la lección Formularios y tablas los maquetaste; ahora vas a leer sus valores, reaccionar mientras se escribe y validarlos con mensajes claros.

Leer el valor de un campo

<label for="nombre">Nombre</label>
<input id="nombre" type="text">
const campoNombre = document.querySelector("#nombre");
console.log(campoNombre.value);   // lo que haya escrito (siempre texto)
CampoQué leerOjo
input de texto, textarea, select.valueSiempre es texto
input type="number" o range.valueAsNumber o Number(.value)Para hacer cuentas
input type="checkbox".checkedtrue o false
input type="color".valueUn color en hexadecimal: "#e63946"
Grupo de radiodocument.querySelector('input[name="talla"]:checked').valueSolo el marcado

Reaccionar mientras se escribe: el evento input

El evento input se dispara con cada cambio: cada letra, cada movimiento del slider. Es el que da la sensación de "tiempo real".

<label for="texto">Tu frase</label>
<textarea id="texto" maxlength="140"></textarea>
<p id="contador" aria-live="polite">0 / 140</p>
const texto = document.querySelector("#texto");
const contador = document.querySelector("#contador");

texto.addEventListener("input", () => {
  contador.textContent = `${texto.value.length} / 140`;
});

aria-live="polite" hace que los lectores de pantalla lean el cambio cuando la persona deja de escribir.

Un personalizador visual con variables CSS

Combinando input con setProperty (lección El DOM) controlas el diseño en vivo:

<label for="color">Color de marca</label>
<input id="color" type="color" value="#2a9d8f">

<label for="radio">Esquinas: <output id="radio-valor">8</output> px</label>
<input id="radio" type="range" min="0" max="40" value="8">
const raiz = document.documentElement;
const color = document.querySelector("#color");
const radio = document.querySelector("#radio");
const radioValor = document.querySelector("#radio-valor");

color.addEventListener("input", () => {
  raiz.style.setProperty("--color-marca", color.value);
});

radio.addEventListener("input", () => {
  raiz.style.setProperty("--radio", `${radio.value}px`);
  radioValor.textContent = radio.value;
});
:root { --color-marca: #2a9d8f; --radio: 8px; }
.tarjeta { border: 3px solid var(--color-marca); border-radius: var(--radio); }

Fíjate en las unidades: a una variable que se usa como medida hay que darle px (o rem), no solo el número. Es la base de la actividad A2.

Enviar un formulario: el evento submit

Escucha el submit del formulario, no el click del botón: así también funciona al pulsar Intro.

const formulario = document.querySelector("#contacto");

formulario.addEventListener("submit", (evento) => {
  evento.preventDefault();          // no recargar la página
  const datos = new FormData(formulario);
  console.log(datos.get("correo"));  // lee cada campo por su atributo name
});

FormData recoge todos los campos que tengan atributo name.

Validar: primero HTML, después JavaScript

HTML ya valida mucho sin JavaScript. Úsalo siempre primero:

<input id="correo" name="correo" type="email" required>
<input id="cp" name="cp" inputmode="numeric" pattern="[0-9]{5}" required>
  • required: obligatorio.
  • type="email", type="url", type="number" con min y max: formato.
  • pattern: una expresión regular (aquí, cinco cifras).
  • minlength y maxlength: longitud del texto.

El navegador no deja enviar el formulario si algo no cumple y muestra su propio aviso. Con CSS puedes marcar los campos con :user-invalid (solo después de que la persona los haya tocado):

input:user-invalid { border-color: #c1121f; }

JavaScript entra cuando quieres mensajes propios o comprobaciones que HTML no hace:

const correo = document.querySelector("#correo");
const error = document.querySelector("#error-correo");

correo.addEventListener("input", () => {
  if (correo.validity.typeMismatch) {
    error.textContent = "Escribe un correo con el formato nombre@dominio.es";
  } else {
    error.textContent = "";
  }
});
<label for="correo">Correo</label>
<input id="correo" name="correo" type="email" required aria-describedby="error-correo">
<p id="error-correo" class="error" aria-live="polite"></p>
  • campo.validity dice qué falla: valueMissing (vacío), typeMismatch (formato), patternMismatch, tooShort…
  • formulario.checkValidity() devuelve true si todo el formulario es válido.
  • aria-describedby asocia el mensaje al campo para los lectores de pantalla.

📌 Nota. La validación en el navegador es para ayudar a la persona, no para proteger nada: cualquiera puede saltársela. La comprobación de seguridad se hace siempre en el servidor.

Buenas prácticas en los mensajes

  • Di qué pasa y cómo arreglarlo: "El código postal tiene 5 cifras", no "Error".
  • Muestra el mensaje junto al campo, no solo en un color rojo (hay quien no distingue el rojo).
  • No valides mientras la persona empieza a escribir un campo vacío: espera a que salga del campo o use :user-invalid.
  • Nunca borres lo que ya ha escrito.

Practica

  1. Un contador de caracteres para una biografía de 160 caracteres que cambia a color de aviso a partir de 140.
  2. Una tarjeta con un selector de color y un slider de tamaño de texto que cambian dos variables CSS y muestran su valor.
  3. Un formulario de suscripción con correo obligatorio: si al enviarlo es válido, sustituye el formulario por un mensaje de "Gracias"; si no, muestra el mensaje junto al campo.

Errores frecuentes

  • Hacer cuentas con .value sin convertirlo: "10" + 5 da "105".
  • Olvidar las unidades al pasar un número a una variable CSS de medida.
  • Escuchar click en el botón de enviar en lugar de submit en el formulario.
  • Olvidar evento.preventDefault() y ver que la página se recarga.
  • Mensajes de error solo en color o sin relación con el campo (aria-describedby).
  • Usar change cuando quieres respuesta inmediata en un slider (es input).

¿Qué es esto?

Soy Cristian Eslava y a veces hago webs para procrastinar yo y vosotros. culTest

La hice en febrero de 2026 para facilitar el aprendizaje de mis alumnos. La idea es aprender desarrollo web practicando y que el proyecto siga creciendo con nuevos temas, tests y retos.

Está inspirada en MDN, W3Schools, CodePen, Manz y muchos otros sitios de documentación sobre desarrollo web. Quería combinar teoría útil, ejemplos ejecutables, retos y el sistema de tests que ya tenía en culTest. culTest

Si te gustó, si no te gustó o si quieres escribirme, puedes hacerlo en cristianeslava@gmail.com