domingo, 21 de noviembre de 2010

EJEMPLO DE CÓMO HACER UN CARRITO DE COMPRAS (CON POCO DE AJAX)

Seguramente alguna vez nos ha tocado (bueno, a mi generación nos tocó) que algún maestro nos deja de trabajo (ya sea de la materia de Sistemas Distribuidos, Programación Web I o II) que realicemos un sitio que involucre vender productos a través de la web.
Lo tradicional sería hacerlo de la manera a como se realiza en una aplicación de escritorio, pero recordar que al trabajar a través de la web, si realizamos muchas peticiones al servidor pues los tiempos de respuestas son muy tardados, además que provocamos sobrecargas a los servidores.
Bueno vamos a dejarnos de choro mareador, en este ejemplo mostraremos una forma sencilla de cómo podemos implementar un carrito de compras, independientemente si trabajamos con PHP, ASP.NET, JAVA,etc. Para lo cual haremos uso del framework Prototype además de las librerías de script.aculo.
El carrito de compras nos permitirá agregar los productos al canasto, ya sea haciendo click en el link “Agregar al carrito” o arrastrando la imagen del producto al canasto (Drag&Drop)
Requerimientos:
·         Framework Prototype
·         Librería script.aculo
·         Visual Studio 2008 (no es necesario)
·         Un café capuccino

Iniciando
Primeramente crearemos una página, la cual puede tener un diseño parecido a la de la imagen siguiente:

Seguramente se estarán riendo, es válido, ya que soy pésimo para las cuestiones de diseño.
En mi caso en mi proyecto tengo la siguiente estructura de los archivos:

En la carpeta “IMÁGENES” almaceno cada una de la foto de los productos de muestra.
En “js”, guardo la librería del framework Prototype, script.aculo y el archivo Carrito.js que explicaré más adelante.
Por último en “stylesheets” guardo las hojas de estilos.

A continuación pongo el código de la página “Default.aspx”:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Web.Pedidos" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>*** Salvador Benítez ***</title>
<link href="stylesheets/common.css" rel="stylesheet" type="text/css" />
<link href="stylesheets/Centro.css" rel="stylesheet" type="text/css" />
<link href="stylesheets/Carrito.css" rel="Stylesheet" type="text/css" />
<script type="text/javascript" language="javascript" src="js/prototype.js"></script>
<script type="text/javascript" language="javascript" src="js/scriptaculous.js"></script>
<script type="text/javascript" language="javascript" src="js/AjaxLib.js"></script>
<script type="text/javascript" language="javascript" src="js/Carrito.js"></script>

</head>
<body>
<form id="Form1" runat="server">
      <!-- encabezado -->
      <div id="header">
            <div class="container">
                  <hr />
     
     
                  <hr />
                 
                  <hr />
            </div>
      </div>
      <!-- contenido principal -->
      <div id="main" class="container">
           
           
            <div id="center">
                  <h3 class="leftbox">Bienvenido al sitio de Salvadorcito.</h3>
                 
                <ul class="EstiloBorde">
                <li><img class="detalleFoto" onload="drag('001,20,Producto1')" id="001,20,Producto1"src="IMAGENES/PERFORADORA.jpg" height="150" width="150" />
           <br/>
           <div class="nombreProducto">Producto1</div>
            <div>Precio:$20</div>
           <div class="agregarProducto" onclick="agregar('001','20','Producto1')">
               Agregar al Carrito</div>
           </li>
          
               <li><img class="detalleFoto" onload="drag('002,50,Producto2')" id="002,50,Producto2"src="IMAGENES/producto1.jpg" height="150" width="150"/>
           <br/>
           <div class="nombreProducto">Producto2</div>
            <div>Precio:$50</div>
           <div class="agregarProducto" onclick="agregar('002','50','Producto2')">
               Agregar al Carrito</div>
           </li>
          
               <li><img class="detalleFoto" onload="drag('003,80,Producto3')" id="003,80,Producto3"src="IMAGENES/producto2.jpg" height="150" width="150" />
           <br/>
           <div class="nombreProducto">Producto3</div>
            <div>Precio:$80</div>
           <div class="agregarProducto" onclick="agregar('003','80','Producto3')">
               Agregar al Carrito</div>
           </li>
          
               <li><img class="detalleFoto" onload="drag('004,150,Producto4')" id="004,150,Producto4"src="IMAGENES/producto3.jpg" height="150" width="150"/>
           <br/>
           <div class="nombreProducto">Producto4</div>
            <div>Precio:$150</div>
           <div class="agregarProducto" onclick="agregar('004','150','Producto4')">
               Agregar al Carrito</div>
           </li>
          
               <li><img class="detalleFoto" onload="drag('005,60,Producto5')" id="005,60,Producto5"src="IMAGENES/mirado.jpg" height="150" width="150"/>
           <br/>
           <div class="nombreProducto">Producto5</div>
            <div>Precio:$60</div>
           <div class="agregarProducto" onclick="agregar('005','60','Producto5')">
               Agregar al Carrito</div>
           </li>

                </ul>
              
          
            </div>
            <!-- carrito -->
            <div id="rightcolumn">
            <h3 class="leftbox">Carrito de Compras</h3>
            <div id="canasto">

            <div id="listaCanasto">
            </div>
            </div>
            <div id="cargando">Pueden poner un cartel al estilo google por ejemplo====Procesando Pedido, Por favor espere...</div>
            <div id="ventanaModal">
            <div id="finalizacion">
            Está a punto de enviar su pedido. Si desea realizar una observacion al
            encargado de papelería anótela a continuacion.<br /><br />
            <%--<div id="listadoprod"></div>--%>
            <table width="100%">
            <tr>
                <td>Observaciones</td>
                <td><input type="text" id="txtNombre" /></td>
            </tr>
            <tr>
                <td></td>
                <td>
                <br />
                <input type="button" id="btnEnviar" value="Enviar" onclick="enviar()" />
                <input type="button" id="btnCancelar" value="Cancelar" onclick="cancelar()" />
                </td>
            </tr>
            </table>
            </div>
            </div>
            </div>
     
      </div>

      </form>
</body>
</html>

La mayor parte del código es pura cuestión de diseño, la parte que comentaremos será la siguiente:
<div id="center">
<h3 class="leftbox">Bienvenido al sitio de Salvadorcito.</h3>
                 
 <ul class="EstiloBorde">
<li><img class="detalleFoto" onload="drag('001,20,Producto1')" id="001,20,Producto1"src="IMAGENES/PERFORADORA.jpg" height="150" width="150"/>

<br/>
<div class="nombreProducto">Producto1</div>
<div>Precio:$20</div>
<div class="agregarProducto" Onclick="agregar('001','20','Producto1')"> Agregar al Carrito</div>
</li>
……
….
Etc,etc,etc
…..
….
 </ul>
</div>
Aquí estamos creando un listado, que será nuestro catalogo de productos, en total tendremos 5 productos.

Las funciones “drag”, “agregar”, las tenemos creadas en el archivo “Carrito.js
A continuación el código de “Carrito.js

window.onload=function(){
Droppables.add("listaCanasto",{
onDrop:sueltaProducto,
accept:["detalleFoto"]
});
$("cargando").style.visibility="hidden";
$("listaCanasto").innerHTML="Carrito Vacio";
//drop('foto');

//Droppables.add("basura",{
//onDrop:tiraProducto,
//accept:["filaCanasto"]
//});
}
var cacheProductos=[];
var canasto=[];

function agregar(id,precio,nombre){
var i=0;
var encontrado=false;

while((i<canasto.length)&&(!encontrado))
{
    if(canasto[i].id==id)
    {
    encontrado=true;
    }
    else
    {
    i++;
    }
}
if(encontrado){
canasto[i].cantidad++;
}
else{
var producto=cacheProductos[id];
nuevoProducto={
'id':id,
'nombre':nombre,
'precio':precio,
'cantidad':1
};
canasto[canasto.length]=nuevoProducto;
}
actualizarCanasto();
}

function actualizarCanasto(){
var contenido="";

if(canasto.length==0){

contenido='';
}
else{
    var filaCanasto=0;
    var total=0;
    for(var i=0;i<canasto.length;i++){
   
    //creo una fila por cada producto
    filaCanasto="<div class='filaCanasto'";
    filaCanasto+="id='canasto_"+canasto[i].id+"'>";
   
    //se arma cada fila con una tabla
    var tablaCanasto;
    tablaCanasto="<table width='100%'><tr>";
    tablaCanasto+="<td class='canastoNombre'>"+canasto[i].nombre+"</td>";
    tablaCanasto+="<td class='canastoCantidad'>"+canasto[i].cantidad+" <img src='images/abajo.jpg' onclick='bajar("+canasto[i].id+")'/><img src='images/arriba.jpg' onclick='subir("+canasto[i].id+")'/></td>";
    tablaCanasto+="<td class='canastoPrecio'>$"+canasto[i].cantidad*canasto[i].precio+"</td>";
    tablaCanasto+="<td><a href='javascript:quitar("+canasto[i].id+")' class='canastoQuitar'>Quitar</a></td>";
    tablaCanasto+="</tr></table>";
    filaCanasto+=tablaCanasto+"</div>";
    contenido+=filaCanasto;
    total+=canasto[i].cantidad*canasto[i].precio;
   

    }
   
    //se muestra el total
    contenido+=generarFilaTotal(total);

    //boton finalizar
    contenido+="<input type='button' id='btnFinalizar' value='Finalizar Pedido' onClick='finalizar()'/>";
}



$("listaCanasto").innerHTML=contenido;


}

function generarFilaTotal(total){

var filaCanasto="<div class='totalCanasto'>"
var tablaCanasto;
tablaCanasto="<table width='100%'><tr>";
tablaCanasto+="<td class='canastoNombre'>TOTAL</td>";
tablaCanasto+="<td class='canastoCantidad'></td>";
tablaCanasto+="<td class='canastoPrecio'>$"+total+"</td>";
tablaCanasto+="<td><a href='javascript:vaciar()' class='canastoQuitar'>Vaciar</a></td>";
tablaCanasto+="</tr></table>";
//alert(tablaCanasto);
filaCanasto+=tablaCanasto+"</div>";

return filaCanasto;
}

//quita un producto del canasto
function quitar(id){
//alert('bien');
var i=0;
var encontrado=false;
while((i<canasto.length)&&(!encontrado)){
//alert(i);
if(canasto[i].id==id){
//alert('encontrado');
encontrado=true;
//lo eliminamos de la lista con prototype
canasto=canasto.without(canasto[i]);
}
else{
i++;
}
}
actualizarCanasto();
}

//aumenta la cantidad de un producto seleccionado
function subir(id){
var i=0;
var encontrado=false;
while((i<canasto.length)&&(!encontrado)){
if(canasto[i].id==id){
encontrado=true;
//aumentamos la cantidad
canasto[i].cantidad++;
}
else{
i++
}
}
actualizarCanasto();
}

//disminuye la cantidad de un producto seleccionado
function bajar(id){
var i=0;
var encontrado=false;
while((i<canasto.length)&&(!encontrado)){
if(canasto[i].id==id){
encontrado=true;
//aumentamos la cantidad
canasto[i].cantidad--;

//si cantidad==0 eliminamos el producto de la lista
if(canasto[i].cantidad==0){
quitar(id);
}
}
else{
i++
}
}
actualizarCanasto();
}

//borra todos los productos que hay en el carrito
function vaciar(){
canasto=[];
actualizarCanasto();
}

//se ejecuta cuando se suelta un producto en el canasto
function sueltaProducto(drag,drop,event){
var array=drag.id.toString().split(",");
agregar(array[0],array[1],array[2]);
}

//quita el producto al arrastrarlo al bote de basura
function tiraProducto(drag,drop,evento){
var id=drag.id.substring(8,drag.id.lenght);
//alert(id);
quitar(id);
}

//conforme se muestran las imagenes las hago dragables
function drag(id){
//alert(id);
new Draggable(id,{revert:true});
}

//formulario de finalizar pedido
function finalizar(){
//alert('q');
if(canasto.length==0){
alert('Su pedido no contiene elementos por procesar');
}
else{
//var contiene="Descripción--Cantidad--Precio</br>";
//for(var i=0;i<canasto.length;i++){
//contiene+=canasto[i].nombre+"--"+canasto[i].cantidad+"--"+canasto[i].precio+"<br/>";
//}
$("ventanaModal").style.visibility="visible";
//$("listadoprod").innerHTML=contiene;
}
}

function cancelar(){
$("ventanaModal").style.visibility="hidden";
}

function enviar(){
$("ventanaModal").style.visibility="hidden";
//$("txtNombre").focus;
$("cargando").style.visibility="visible";


alert("Y AQUI REALIZARIA LA COMPRA...");
$("cargando").style.visibility="hidden";
//alert(parametros);
vaciar();
}

Nuestra pequeña página nos permitirá hacer lo siguiente:

Si arrastramos la imagen de un producto y la soltamos en el área del carrito de compras, automáticamente la agregará al canasto:

Si deseamos aumentar la cantidad del producto, solo es necesario hacer clic en las flechitas..

Bueno pues eso es todo, creo que el código no merece tanta explicación, cualquier duda, comentario escríban a mi correo o en mi facebook. Se me  olvidaba, de esta manera hice parte de mi proyecto de residencia.

domingo, 21 de noviembre 12:45:24 a.m.
J

El código fuente lo pueden encontrar aquí: http://bit.ly/93uYYr

4 comentarios:

  1. Excelente post...tendrias uno con clases y base de datos. Te agradeceria, pues me han dejado un trabajo.Gracias


    Atte.

    PePe Ecca --> email : pepex_ecca@hotmail.com

    ResponderEliminar
  2. no manejas base de datos en este??

    ResponderEliminar
  3. En este ejemplo no, el contenido fue generado de forma estática, ilustra la funcionalidad del lado del cliente. El código es ya obsoleto(fue diseñado hace mas de 4 años).

    ResponderEliminar
  4. excelente carrito, gracis por swu ayuda.
    Tengo una solicitud:
    Mew podrian ayudar a generar una opcion para cobro de envio según la zona; digamos que hay 5 zonas de envío y cada una tiene diferente costo.

    ResponderEliminar