Sweetalert 2 y ventas - mostrar cambio calculado según importe y pago de cliente

Sweetalert 2 – Mostrar total de venta y cambio a partir de pago

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

Sweetalert 2 y ventas - mostrar cambio calculado según importe y pago de cliente
Sweetalert 2 y ventas – mostrar cambio calculado según importe y pago de cliente

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.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *