Formularios en JavaScript: preventDefault y localStorage
Resumen
Domina el flujo completo de un formulario en JavaScript: evita recargas con event.preventDefault(), captura datos con FormData, persiste un objeto con JSON en localStorage y renderiza el último mensaje guardado en la interfaz. Todo con buenas prácticas de DOM, nombres coherentes y una UX fluida.
¿Cómo preparar el HTML y evitar errores al copiar y pegar?
Antes de empezar, crea una carpeta nueva llamada Form y separa tu trabajo anterior del DOM para conservar el historial. Copia index.html y app.js, pero verifica que las rutas y los IDs coincidan para no heredar errores silenciosos por copiar y pegar.
Crea la sección del formulario antes del cierre de main.
Usa un ID claro para el formulario: por ejemplo, id="contact-form".
Define atributos name coherentes: name para el input de nombre y message para el textarea.
Agrega un botón con type="submit".
Aplica estilos al final del archivo de estilos, con una clase hidden para ocultar bloques hasta mostrarlos.
Valida en el navegador con Live Server que la interfaz cargue y que el envío no haga nada todavía.
Clave: el atributo name es lo que la API de FormData utiliza para extraer valores. Si cambias name en HTML, actualiza las lecturas en JavaScript.
¿Cómo manejar el submit con event.preventDefault y FormData?
El patrón base de formularios en JavaScript es simple: escuchar el submit, prevenir el comportamiento por defecto y leer los datos desde event.target usando FormData.
// buena práctica: clave única para localStorageconstCONTACT_STORAGE_KEY='form';// 1) render está arriba para poder llamarse desde el submitfunctionrenderSavedMessages(){const box =document.querySelector('#mensaje-guardado');const raw =localStorage.getItem(CONTACT_STORAGE_KEY);if(!box ||!raw)return;const data =JSON.parse(raw); box.classList.remove('hidden'); box.innerHTML=`<p><strong>Último mensaje guardado:</strong></p><p><strong>Nombre:</strong>${data.name}</p><p><strong>Mensaje:</strong>${data.message}</p>`;}// 2) manejar el envío del formulariofunctionhandleContactSubmit(event){ event.preventDefault();// evita recarga y envío por URLconst form = event.target;// el <form> que disparó el eventoconst formData =newFormData(form);const name =String(formData.get('name'));const message =String(formData.get('message'));const payload ={ name, message,date:newDate().toISOString(),// timestamp ISO};localStorage.setItem(CONTACT_STORAGE_KEY,JSON.stringify(payload)); form.reset();renderSavedMessages();// actualiza la UI tras guardar}// 3) registrar el listener cuando el formulario existaconst contactForm =document.querySelector('#contact-form');if(contactForm){ contactForm.addEventListener('submit', handleContactSubmit);}// 4) mostrar datos guardados al cargar la páginarenderSavedMessages();
Puntos clave que aparecen y cómo se usan:
event.preventDefault(): bloquea la recarga y el envío por parámetros en la URL.
event.target: referencia directa al formulario que emitió el evento.
FormData API: permite leer valores con formData.get('name').
Atributo name: debe corresponder con las llaves que lee FormData: 'name' y 'message'.
Date.toISOString(): genera una marca de tiempo legible y consistente.
localStorage.setItem + JSON.stringify: guarda un objeto como string.
form.reset(): limpia los campos después de guardar.
addEventListener('submit', ...): escucha el submit sin mezclar JS con HTML.
¿Cómo leer localStorage y renderizar el último mensaje guardado?
Para presentar el último mensaje guardado en la interfaz, obtén la cadena desde localStorage, conviértela a objeto con JSON.parse, quita la clase hidden y reemplaza el contenido con innerHTML.
Usa localStorage.getItem para leer la clave CONTACT_STORAGE_KEY.
Aplica JSON.parse para volver a objeto.
Manipula la UI con classList.remove('hidden') e innerHTML usando plantillas.
Inspecciona en DevTools: pestaña Application, sección Storage, opción Local Storage.
Buenas prácticas que se mencionan y conviene aplicar:
Define constantes descriptivas para claves: storage key clara y en snake_case o mayúsculas con guiones bajos.
Separa proyectos en carpetas para mantener el historial y evitar romper avances previos.
Evita errores por copiar y pegar: verifica IDs, names y rutas.
Considera validaciones mínimas antes de guardar, por ejemplo: que el mensaje tenga diez caracteres.
Piensa en escalabilidad: enviar a una API o base de datos cuando sea necesario.
¿Tienes una mejora o un reto resuelto, como validaciones adicionales o un listado histórico de mensajes? Compártelo en los comentarios y cuéntanos tu enfoque para seguir aprendiendo juntos.
Comparto mis notas de esta clase, explicando los pasos del código. Como los pasos no fueron de manera completamente lineales, ya que se estuvo añadiendo en distintos puntos del código según se necesitaba, intenté documentarlo lo más acertado posible:
Se inicia con la función handleContactSubmmit(event) y lo primero que se hace es desactivar el comportamiento default de recargar la páginal al submit. Se usa event.preventDefault(), esto permite seguir capturando información o trabajando.
Se pasa a obtener el formulario, se crea la constante form=event.target;
Se accede a la información del form con formData=new FormData(form);
Se obtienen los campos del form como Nombre y mensaje, declarándolas como variables y asignándoles String(formData.get('variable'));
Se crea un objeto con los datos completos, se declara como payload y se le añade el campo de date, que es un new Date().toISOString()
Se usa la API que permite trabajar con localStorage guardando llave - valor: localStorage.setItem(CONTACT_STORAGE_KEY, JSON.stringify(payload)); //aquí se crea la variable que va a ser la llave de la información, pero debe ser declarada hasta arriba porque así evitas escribir el nombre de la llave manualmente en varios lugares. Si algún día decides cambiar el nombre de esa llave, solo lo modificas en una línea y listo, el resto de tu código no se rompe.
Se usa form.reset() para limpiar los datos del form al final
A continuación, se registra el manejador de eventos para señalar que este formulario existe y puede ser utilizado, se crea contactForm, que usa querySelector para extraer #contact-form. Se valida si existe con un if y se le añade un addEventListener('submit', handleContactSubmit);
Como esto no muestra los datos, pero sí los guarda, se procede a crear la función que puede mostrarlos en la página:
Se crea la función de renderSavedMessage(), el cual llama a la caja del contenido (#mensaje-guardado) para obtenerlo, después obtiene su info con localStorage.getItem(CONTACT_STORAGE_KEY);
después se hace parse a esa data obtenida de localStorage con JSON.parse();
Se procede a remover la clase hidden de box para hacerlo visible.
se modifica el contenido de box mediante innerHTML y se le añade el bloque usando template literals, asignando los valores del último registro guardado.
Se añade renderSavedMessage() antes del form reset creado anteriormente
Código del reto 24-formularios-javascript con instrucciones: