Anexsoft | Blog y dictado de cursos de Tecnología

En este encontrarás tutoriales de tecnología como PHP, ASP.NET MVC, Front-End, entre otros y cursos exigentes de modalidad online que te ayudarán a crecer profesionalmente.

Creando un facturador con Javascript y JSRender
Actualizado el 28 Noviembre, 2015 y leído 8,640 veces
Calificación: 9.20 / 10

Creando un facturador con Javascript y JSRender

Anexsoft

El objetivo de esta entrada es crear un facturador usando solo jQuery y JSRender, donde los datos que iremos procesando lo vamos a guardar en la memoria RAM del cliente, posteriormente toda esta información deberíamos enviarlo al servidor.

 

Creando nuestro objeto para trabajar el facturador

Debemos crear un objeto que represente a nuestro facturador, por lo cual este implementará los métodos de actualizar/registrar/eliminar y refrescar el detalle. Asimismo, tendra las propiedades necesarias para guardar los productos que hemos elegido, y calcular el subtotal, total e IGV.

var facturador = {
    detalle: {
        igv: 0,
        total: 0,
        subtotal: 0,
        items: []
    },
    /* Encargado de agregar un producto a nuestra colección */
    registrar: function(item) {},
    /* Encargado de actualizar el precio/cantidad de un producto */
    actualizar: function(id, row) {},
    /* Encargado de retirar el producto seleccionado */
    retirar: function(id) {},
    /* Refresca todo los productos elegidos */
    refrescar: function() {}
};

Nuestro objeti ha quedado de esta manera, el cual implementa lo necesario para calcular todo desde el lado del cliente.

 

Creando nuestro formulario para registrar un detalle

Vamos a crear un pequeño formulario que nos permita registrar el detalle del producto elegido, para ello debemos ingresar el nombre, precio y cantidad, luego presionaremos el botón de agregar.

Image title

Ahora que tenemos el formulario debemos crear un evento para el boton #btn-agregar.

$(document).ready(function() {
    $("#btn-agregar").click(function() {
        facturador.registrar({
            producto: $("#producto").val(),
            cantidad: $("#cantidad").val(),
            precio: $("#precio").val(),
        });
        $("#producto").val('');
        $("#precio").val('');
        $("#cantidad").val('');
    })
})

Como se dan cuenta, este llama a nuestro objeto facturador y le dice que ejecute el método registrar y le pasamos un objeto hijo.

La implementación de nuestro método registrar es la siguiente:

registrar: function(item) { /* Agregamos el total */
    item.total = (item.cantidad * item.precio);
    this.detalle.items.push(item);
    this.refrescar();
}

Este se encarga de calcular el total para cada nuevo producto elegido, esto lo sabemos multiplicando la cantidad por el total.

 

Creando nuestra plantilla para mostrar el detalle de los productos

Debemos crear una plantilla que se encargue de mostrar la información dentro de nuestro objeto facturador.

<script id="facturador-detalle-template" type="text/x-jsrender" src=""> {{for items}}
    <li class="list-group-item">
        <div class="row">
            <div class="col-xs-7">
                <div class="input-group"> <span class="input-group-btn">                        <button class="btn btn-danger form-control" class="btn-retirar">                            <i class="glyphicon glyphicon-minus"></i>                        </button>                    </span>
                    <input name="producto" class="form-control" type="text" placeholder="Nombre del producto" value="{{:producto}}" /> </div>
            </div>
            <div class="col-xs-1">
                <input name="cantidad" class="form-control" type="text" placeholder="Cantidad" value="{{:cantidad}}" /> </div>
            <div class="col-xs-2">
                <div class="input-group"> <span class="input-group-addon">                  <input name="precio" class="form-control" type="text" placeholder="Precio" value="{{:precio}}" />                </div>            </div>            <div class="col-xs-2">                <div class="input-group">                    <span class="input-group-addon">S/.</span>
                    <input class="form-control" type="text" readonly value="{{:total}}" /> <span class="input-group-btn">                        <button class="btn btn-success form-control" class="btn-retirar">                            <i class="glyphicon glyphicon-refresh"></i>                        </button>                    </span> </div>
            </div>
        </div>
    </li> {{else}}
    <li class="text-center list-group-item">No se han agregado productos al detalle</li> {{/for}}
    <li class="list-group-item">
        <div class="row text-right">
            <div class="col-xs-10 text-right"> Sub Total </div>
            <div class="col-xs-2"> <b>{{:subtotal}}</b> </div>
        </div>
    </li>
    <li class="list-group-item">
        <div class="row text-right">
            <div class="col-xs-10 text-right"> IGV (18%) </div>
            <div class="col-xs-2"> <b>{{:igv}}</b> </div>
        </div>
    </li>
    <li class="list-group-item">
        <div class="row text-right">
            <div class="col-xs-10 text-right"> Total </div>
            <div class="col-xs-2"> <b>{{:total}}</b> </div>
        </div>
    </li>
</script>
  • Nuestra plantilla lo que hace es recorrer dentro de nuestro objeto facturador el indice detalle.items, el cual contiene todos los productos elegido y para esto usamos un for de JSRender. Lo que me gusta del for del JSRender que tiene la opción ELSE que nos sirve para mostrar algo cuando no existan elementos a mostrar.

  • Después de cerrar el for, mostramos el SubTotal, IGV y Total de nuestro objeto facturador que se encuentra en el indice detalle.

Con esto ya tenemos todo nuestra plantilla realizada, ahora debemos agregarla a un elemento HTML para que sea visualizado, como he trabajado con etiquetas <li>, lo voy agregar dentro de un <ul>.

<ul id="facturador-detalle" class="list-group"></ul>

El encargado de parsear nuestra data con el template lo va hacer nuestro método refrescar(), que esta en nuestro objeto facturador.

refrescar: function()
{
    this.detalle.total = 0;

    /* Declaramos un id y calculamos el total */
    $(this.detalle.items).each(function(indice, fila){
        facturador.detalle.items[indice].id = indice;
        facturador.detalle.total += fila.total;
    })

    /* Calculamos el subtotal e IGV */
    this.detalle.igv      = (this.detalle.total * 0.18).toFixed(2); // 18 % El IGV y damos formato a 2 deciamles
    this.detalle.subtotal = (this.detalle.total - this.detalle.igv).toFixed(2); // Total - IGV y formato a 2 decimales
    this.detalle.total    = this.detalle.total.toFixed(2);

    var template   = $.templates("#facturador-detalle-template");
    var htmlOutput = template.render(this.detalle);

    $("#facturador-detalle").html(htmlOutput);
}


Implementando los métodos de actualizar/registrar

En nuestro template, si han revisado el código hay 2 botones uno para eliminar y otro para registrar, cada uno tiene una propiedad onclick que llama a su método respectivo.

<button class="btn btn-danger form-control">
 <i class="glyphicon glyphicon-minus"></i>
</button>
<button class="btn btn-success form-control" class="btn-retirar">
 <i class="glyphicon glyphicon-refresh"></i>
</button>

Y los métodos dentro del objeto facturador.

/* Encargado de agregar un producto a nuestra colección */
registrar: function(item)
{
    /* Agregamos el total */
    item.total = (item.cantidad * item.precio);

    this.detalle.items.push(item);

    this.refrescar();
},

/* Encargado de actualizar el precio/cantidad de un producto */
actualizar: function(id, row)
{
    /* Capturamos la fila actual para buscar los controles por sus nombres */
    row = $(row).closest('.list-group-item');

    /* Buscamos la columna que queremos actualizar */
    $(this.detalle.items).each(function(indice, fila){
        if(indice == id)
        {
            /* Agregamos un nuevo objeto para reemplazar al anterior */
            facturador.detalle.items[indice] = {
                producto: row.find("input[name='producto']").val(),
                cantidad: row.find("input[name='cantidad']").val(),
                precio:   row.find("input[name='precio']").val()
            };

            facturador.detalle.items[indice].total = facturador.detalle.items[indice].precio *
                                                     facturador.detalle.items[indice].cantidad;

            return false;
        }
    })

    this.refrescar();
}

 

Removiendo un fila de nuestro detalle

Para remover una fila, hemos creado adicionalmente un botón en el template y le hemos declarado un evento onclick.

<button class="btn btn-danger form-control">
 <i class="glyphicon glyphicon-minus"></i>
</button>
retirar: function(id)
{
    /* Declaramos un ID para cada fila */
    $(this.detalle.items).each(function(indice, fila){
        if(indice == id)
        {
            facturador.detalle.items.splice(id, 1);
            return false;
        }
    })

    this.refrescar();
},

Conclusión

De esta manera ganamos un gran performance en velocidad y evitamos trabajar directamente con la base de datos, al final cuando nuestro usuario haya decidido dar por finalizada la factura, recien ahí debemos mandar toda la información de nuestro template al servidor para guardarla en la base de datos.

¡Adquiera ya!

  • Código de fuente de Red Social desarrollada en ASP.NET MVC

    Código de fuente de Red Social desarrollada en ASP.NET MVC
  • Software de Portafolio Profesional hecho en ASP.NET MVC 5 C#

    Software de Portafolio Profesional hecho en ASP.NET MVC 5 C#
  • Software de Venta e Inventario hecho en PHP y Codeigniter

    Software de Venta e Inventario hecho en PHP y Codeigniter

Últimas publicaciones

Encuesta

¿Cómo nos conociste?

Síguenos

Estudia con nosotros y crece profesionalmente

Nuestros cursos han sido hecho en base a lo que demanda el mercado hoy en día.
La experiencia obtenida es la de un ambiente laboral.

Anexsoft
© 2017 Anexsoft, blog y cursos online de TI.