A partir de este ejercicio comenzamos a trabajar con el API de FETCH. Para este ejercicio vamos a crear un archivo llamado contact-form.html, que va a tener la siguiente sintaxis.
Sintaxis de contact-form.html.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Envío de formulario con Fetch y FormSubmit</title> <style> html { box-sizing: border-box; font-family: sans-serif; font-size: 16px; } *, *::before, *::after { box-sizing: inherit; } /* **** ContactForm Validations **** */ .contact-form { --form-ok-color: #4caf50; --form-error-color: #f44336; margin-left: auto; margin-right: auto; width: 80%; } .contact-form > * { padding: 0.5rem; margin: 1rem auto; display: block; width: 100%; } .contact-form textarea { resize: none; } .contact-form legend, .contact-form-response { font-size: 1.5rem; font-weight: bold; text-align: center; } .contact-form input, .contact-form textarea { font-size: 1rem; font-family: sans-serif; } .contact-form input[type="submit"] { width: 50%; font-weight: bold; cursor: pointer; } .contact-form *::placeholder { color: #000; } .contact-form [required]:valid { border: thin solid var(--form-ok-color); } .contact-form [required]:invalid { border: thin solid var(--form-error-color); } .contact-form-error { margin-top: -1rem; font-size: 80%; background-color: var(--form-error-color); color: #fff; transition: all 800ms ease; } .contact-form-error.is-active { display: block; animation: show-message 1s 1 normal 0s ease-out both; } .contact-form-loader { text-align: center; } .none { display: none; } @keyframes show-message { 0% { visibility: hidden; opacity: 0; } 100% { visibility: visible; opacity: 1; } } </style> </head> <body> <form class="contact-form"> <legend>Envía tus comentarios</legend> <input type="text" name="name" placeholder="Escribe tu nombre" title="Nombre sólo acepta letras y espacios en blanco" pattern="^[A-Za-zÑñÁáÉéÍíÓóÚúÜü\s]+$" required /> <input type="email" name="email" placeholder="Escribe tu correo" title="Email incorrecto" pattern="^[a-z0-9]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,15})$" required /> <input type="text" name="subject" placeholder="Asunto a tratar" title="El asunto es requerido" required /> <textarea name="comments" cols="50" rows="5" placeholder="Escribe tus comentarios" data-pattern="^.{1,255}$" title="Tu comentario no debe sobrepasar los 255 caracteres" required ></textarea> <input type="submit" value="Enviar" /> <div class="contact-form-loader none"> <img src="loader.svg" alt="Cargando" /> </div> <div class="contact-form-response none"> <p>Los datos han sido enviados</p> </div> </form> <script> const d = document; function contactForm() { const $form = d.querySelector(".contact-form"), $inputs = d.querySelectorAll(".contact-form [required]"); // console.log($imputs); $inputs.forEach((input) => { const $span = d.createElement("span"); $span.id = input.name; $span.textContent = input.title; $span.classList.add("contact-form-error", "none"); input.insertAdjacentElement("afterend", $span); }); d.addEventListener("keyup", (e) => { if (e.target.matches(".contact-form [required]")) { let $input = e.target, pattern = $input.pattern || $input.dataset.pattern; // console.log($input, pattern); if (pattern && $input.value !== "") { // console.log("El input tiene patrón"); let regex = new RegExp(pattern); return !regex.exec($input.value) ? d.getElementById($input.name).classList.add("is-active") : d.getElementById($input.name).classList.remove("is-active"); } if (!pattern) { // console.log("El input NO tiene patrón"); return $input.value === "" ? d.getElementById($input.name).classList.add("is-active") : d.getElementById($input.name).classList.remove("is-active"); } } }); d.addEventListener("submit", (e) => { e.preventDefault(); const $loader = d.querySelector(".contact-form-loader"), $response = d.querySelector(".contact-form-response"); $loader.classList.remove("none"); fetch("https://formsubmit.co/ajax/youremail@gmail.com", { method: "POST", body: new FormData(e.target), }) .then((res) => (res.ok ? res.json() : Promise.reject(res))) .then((json) => { $loader.classList.add("none"); $response.classList.remove("none"); $response.innerHTML = `<p>${json.message}</p>`; $form.reset(); }) .catch((err) => { console.log(err); let message = err.statusText || "Ocurrió un error al enviar el formulario"; $response.innerHTML = `<p>Error ${err.status}: ${message}</p>`; }) .finally(() => { setTimeout(() => { $response.classList.add("none"); $response.innerHTML = ``; }, 3000); }); }); } d.addEventListener("DOMContentLoaded", contactForm()); </script> </body> </html>