004. Envío Formulario con Fetch y FormSubmit
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>