En este post sobre Sweetalert 2 (Sweet Alert 2) veremos un ejercicio práctico: cómo solicitar el pago del cliente y mostrar el cambio (Dinero que se devuelve al comprador cuando entrega una cantidad superior al importe) en la misma alerta, validando todo.
Veremos cómo escuchar el cambio del input de la alerta, modificar el HTML de la misma y validar según una variable externa.
Recomiendo ver el tutorial de SweetAlert2 antes de leer este artículo.
Mostrar alerta con total de venta e input
Primero que nada vamos a necesitar el total de la venta, obtenerlo está fuera de los límites de este tutorial, para fines prácticos yo definiré el total como una constante.
const TOTAL_VENTA = 30;
Vamos a mostrar la alerta con input
en number
para que muestre una caja de texto solicitando el pago del cliente, luego vamos a esperar el evento para que la alerta haya sido mostrada.
const resultado = await Swal
.fire({
input: "number",
html: `
<h2>Total: <small >$${TOTAL_VENTA.toFixed(2)}</small></h2>
<h1>Cambio: <small id="cambio"></small></h1>
`,
showCancelButton: true,
confirmButtonText: "Ok",
cancelButtonText: "Cancelar",
});
También vamos a inyectar HTML en la alerta, y dentro de ese HTML estará un elemento que mostrará el cambio conforme el pago se vaya escribiendo.
Ese elemento debe tener un ID que vamos a recuperar con querySelector.
Calculando cambio
Una vez que estemos en el evento de la alerta mostrada, entonces vamos a escuchar el “change” del input y dentro del mismo calcular el cambio.
didOpen: () => {
const input = Swal.getInput()
const $cambio = Swal.getHtmlContainer().querySelector(
"#cambio");
input.oninput = () => {
$cambio.textContent = "";
const cambio = parseFloat(input.value) - TOTAL_VENTA;
if (cambio > 0) {
$cambio.textContent = `$${cambio.toFixed(2)}`;
}
}
},
Aquí vemos unas cosas muy importantes. Primero vemos el evento didOpen
que se desencadena cuando la alerta se ha abierto.
Luego podemos obtener una referencia al elemento del input con Swal.getInput()
y también podemos obtener elementos que estén dentro del contenedor como se ve en la línea 3.
Más adelante en la línea 5 escuchamos el cambio del input, que es en el evento oninput
propio de Sweet alert y calculamos el cambio. Mostramos el cambio solo si el mismo es mayor a 0.
Validando
Finalmente veamos cómo validar que el pago del cliente sea mayor o igual al total del importe de la venta al usar Sweetalert2.
Para ello vamos a usar inputValidator
, que recibe una definición de función cuyo primer parámetro será el valor del input:
inputValidator: pago => {
if (!pago || pago < TOTAL_VENTA) {
return "El pago debe ser mayor o igual al total de la venta";
} else {
return undefined;
}
},
Recuerda que la validación se desencadena cuando el usuario hace clic en el botón “Ok”, y si la misma regresa una cadena entonces la alerta mostrará el error.
Poniendo todo junto
En mi caso el código completo queda así. Puedes usar async
y await
o promesas, yo uso lo primero porque el código queda más limpio pero recuerda que debes estar dentro de una función async
para usar await
:
const TOTAL_VENTA = 30;
const resultado = await Swal
.fire({
title: "Escriba el pago del cliente para calcular el cambio",
input: "number",
inputValidator: pago => {
if (!pago || pago < TOTAL_VENTA) {
return "El pago debe ser mayor o igual al total de la venta";
} else {
return undefined;
}
},
html: `
<h2>Total: <small >$${TOTAL_VENTA.toFixed(2)}</small></h2>
<h1>Cambio: <small id="cambio"></small></h1>
`,
didOpen: () => {
const input = Swal.getInput()
const $cambio = Swal.getHtmlContainer().querySelector(
"#cambio");
input.oninput = () => {
$cambio.textContent = "";
const cambio = parseFloat(input.value) - TOTAL_VENTA;
if (cambio > 0) {
$cambio.textContent = `$${cambio.toFixed(2)}`;
}
}
},
showCancelButton: true,
confirmButtonText: "Ok",
cancelButtonText: "Cancelar",
});
if (resultado.value) {
const input = Object.assign(document.createElement("input"), {
value: "terminar",
name: "accion",
type: "hidden",
});
$formularioTerminarVenta.append(input);
$formularioTerminarVenta.submit();
}
Desde la línea 33 estoy comprobando si la alerta fue cerrada con un valor válido escrito en ella, y en ese caso inyecto un input al formulario y lo envío. Eso es más específico a lo que yo necesitaba.
Obviamente en tu caso puedes hacer otra cosa dentro del if
. Si el programa llega a ese punto es porque el usuario escribió una cantidad correcta y ya puedes dar por terminada la venta o cualquier cosa.
Para terminar te dejo con más tutoriales de JavaScript en mi blog.