diff --git a/plugins/shopping_cart/public/cart.js b/plugins/shopping_cart/public/cart.js new file mode 100644 index 0000000..d24c79c --- /dev/null +++ b/plugins/shopping_cart/public/cart.js @@ -0,0 +1,246 @@ +function Cart(config) { + var $ = jQuery; + Cart.instance = this; // this may be a list on the future; + this.cartElem = $("#cart1")[0]; + this.cartElem.cartObj = this; + this.contentBox = $("#cart1 .cart-content"); + this.itemsBox = $("#cart1 .cart-items"); + this.items = {}; + this.visible = false; + if (config.hasProducts) { + $(this.cartElem).show(); + this.enterprise = config.enterprise; + this.listProducts(); + } + $(".cart-buy", this.cartElem).button({ icons: { primary: 'ui-icon-cart'} }); +} + +(function($){ + + Cart.prototype.listProducts = function() { + var me = this; + $.ajax({ + url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/list', + dataType: 'json', + success: function(data, ststus, ajax){ + if ( !data.ok ) alert(data.error.message); + else me.addToList(data, true); + }, + cache: false, + error: function(ajax, status, errorThrown) { + alert('List cart items - HTTP '+status+': '+errorThrown); + } + }); + } + + Cart.prototype.addToList = function(data, clear) { + if( clear ) this.itemsBox.empty(); + var me = this; + for( var item,i=0; item=data.products[i]; i++ ) { + this.items[item.id] = { price:item.price, quantity:item.quantity }; + this.updateTotal(); + var liId = "cart-item-"+item.id; + var li = $("#"+liId); + if( !li[0] ) li = $('
  • \n').appendTo(this.itemsBox); + li.empty(); + $('
    ' + + ''+ item.name +'' + + '
    ' + + ''+ (item.price ? '× '+ item.price : '') +'
    ' + + ' remove' + ).appendTo(li); + var input = $("input", li)[0]; + input.lastValue = input.value; + input.itemId = item.id; + input.ajustSize = function() { + var len = this.value.toString().length; + if(len > 2) len--; + this.style.width = len+"em"; + }; + input.ajustSize(); + input.onchange = function() { + me.updateQuantity(this, this.itemId, this.value); + }; + document.location.href = "#"+liId; + document.location.href = "#"+this.cartElem.id; + history.go(-2); + var liBg = li.css("background-color"); + li[0].style.backgroundColor = "#FF0"; + li.animate({ backgroundColor: liBg }, 1000); + } + if( !this.visible ) { + this.contentBox.hide(); + this.show(); + } + } + + Cart.prototype.updateQuantity = function(input, itemId, quantity) { + quantity = parseInt(quantity); + input.disabled = true; + var originalBg = input.style.backgroundImage; + input.style.backgroundImage = "url(/images/loading-small.gif)"; + var me = this; + if( quantity == NaN ) return input.value = input.lastValue; + $.ajax({ + url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/update_quantity/'+ itemId +'?quantity='+ quantity, + dataType: 'json', + success: function(data, status, ajax){ + if ( !data.ok ) { + alert(data.error.message); + input.value = input.lastValue; + } + else { + input.lastValue = quantity; + me.items[itemId].quantity = quantity; + me.updateTotal(); + } + }, + cache: false, + error: function(ajax, status, errorThrown) { + alert('Add item - HTTP '+status+': '+errorThrown); + input.value = input.lastValue; + }, + complete: function(){ + input.disabled = false; + input.style.backgroundImage = originalBg; + input.ajustSize(); + } + }); + } + + Cart.prototype.removeFromList = function(itemId) { + $("#cart-item-"+itemId).slideUp(500, function() {$(this).remove()}); + delete this.items[itemId]; + this.updateTotal(); + } + + Cart.addItem = function(enterprise, itemId, link) { + // on the future, the instance may be found by the enterprise identifier. + link.intervalId = setInterval(function() { + steps = ['w', 'n', 'e', 's']; + if( !link.step || link.step==3 ) link.step = 0; + link.step++; + $(link).button({ icons: { primary: 'ui-icon-arrowrefresh-1-'+steps[link.step]}, disable: true }) + }, 100); + var stopBtLoading = function() { + clearInterval(link.intervalId); + $(link).button({ icons: { primary: 'ui-icon-cart'}, disable: false }); + }; + this.instance.addItem(enterprise, itemId, stopBtLoading); + } + + Cart.prototype.addItem = function(enterprise, itemId, callback) { + if(!this.enterprise) { + this.enterprise = enterprise; + if( !this.visible ) $(this.cartElem).show(); + } + var me = this; + $.ajax({ + url: '/profile/'+ enterprise +'/plugins/shopping_cart/add/'+ itemId, + dataType: 'json', + success: function(data, status, ajax){ + if ( !data.ok ) alert(data.error.message); + else me.addToList(data); + }, + cache: false, + error: function(ajax, status, errorThrown) { + alert('Add item - HTTP '+status+': '+errorThrown); + }, + complete: callback + }); + } + + Cart.removeItem = function(enterprise, itemId) { + var message = this.instance.cartElem.getAttribute('data-l10nRemoveItem'); + if( confirm(message) ) this.instance.removeItem(enterprise, itemId); + } + + Cart.prototype.removeItem = function(enterprise, itemId) { + if ($("li", this.itemsBox).size() < 2) return this.clean(); + var me = this; + $.ajax({ + url: '/profile/'+ enterprise +'/plugins/shopping_cart/remove/'+ itemId, + dataType: 'json', + success: function(data, status, ajax){ + if ( !data.ok ) alert(data.error.message); + else me.removeFromList(data.product_id); + }, + cache: false, + error: function(ajax, status, errorThrown) { + alert('Remove item - HTTP '+status+': '+errorThrown); + } + }); + } + + Cart.toggle = function(link) { + link.parentNode.parentNode.cartObj.toggle(); + } + Cart.prototype.toggle = function() { + this.visible ? this.hide() : this.show(); + } + + Cart.prototype.show = function() { + this.visible = true; + this.contentBox.slideDown(500); + $(".cart-toggle .str-show", this.cartElem).hide(); + $(".cart-toggle .str-hide", this.cartElem).show(); + + } + Cart.prototype.hide = function() { + this.visible = false; + this.contentBox.slideUp(500); + $(".cart-toggle .str-show", this.cartElem).show(); + $(".cart-toggle .str-hide", this.cartElem).hide(); + } + + Cart.prototype.updateTotal = function() { + var total = 0; + var currency, sep = ""; + for( var itemId in this.items ) { + var item = this.items[itemId]; + if( item.price ) { + currency = item.price.replace(/^([^0-9]+).*$/, "$1"); + sep = item.price.charAt(item.price.length-3); + var price = item.price.replace(/[^0-9]/g,""); + total += item.quantity * parseFloat(price); + } + } + total = Math.round(total).toString().replace(/(..)$/, sep+"$1") + $(".cart-total b", this.cartElem).text( ( (total!=0) ? currency+" "+total : "---" ) ); + } + + Cart.clean = function(link) { + var message = this.instance.cartElem.getAttribute('data-l10nCleanCart'); + if( confirm(message) ) link.parentNode.parentNode.parentNode.cartObj.clean(); + } + + Cart.prototype.clean = function() { + var me = this; + $.ajax({ + url: '/profile/'+ me.enterprise +'/plugins/shopping_cart/clean', + dataType: 'json', + success: function(data, status, ajax){ + if ( !data.ok ) alert(data.error.message); + else{ + me.items = {}; + $(me.cartElem).slideUp(500, function() { + $(me.itemsBox).empty(); + me.hide(); + me.enterprise = null; + me.updateTotal(); + }); + } + }, + cache: false, + error: function(ajax, status, errorThrown) { + alert('Remove item - HTTP '+status+': '+errorThrown); + } + }); + } + + $(function(){ + $('.cart-add-item').button({ icons: { primary: 'ui-icon-cart'} }) + }); + +})(jQuery); diff --git a/plugins/shopping_cart/public/style.css b/plugins/shopping_cart/public/style.css new file mode 100644 index 0000000..d9e3b32 --- /dev/null +++ b/plugins/shopping_cart/public/style.css @@ -0,0 +1,106 @@ +.cart-add-item { + position: absolute; + right: 5px; + top: 5px; +} + +.cart { + position: absolute; + right: 20px; + top: 0px; + width: 200px; + z-index: 1000; + border: 1px solid #777; + border-top: none; + background: rgba(200,200,200,0.6); +} + +.cart h3 { + color: #888; + margin: 0px 0px 0px 5px; +} + +.cart-clean { + color: #AAA; + position: absolute; + top: 1px; + right: 5px; + text-decoration: none; +} +.cart-clean:hover { + color: #888; +} + +.cart-content { + display: none; +} + +.cart-items { + margin: 0px; + padding: 0px; + max-height: 328px; + overflow: auto; +} + +.cart-items li { + height: 50px; + padding: 5px; + margin: 3px; + border: 1px solid #999; + list-style: none; + background: #FFF; + position: relative; +} + +.cart-items .picture { + float: left; + width: 50px; + height: 50px; + margin-right: 10px; + background-repeat: no-repeat; + background-position: 50% 50%; +} + +.cart .item-name { + margin-right: 20px; +} + +.cart .button { + position: absolute; + top: 2px; + right: 2px; +} + +.cart input { + border: 1px solid transparent; + background: transparent 50% 50% no-repeat; + text-align: center; + padding: 0px; + font-family: monospace; + width: 2em; +} +.cart:hover input, .cart input:focus { + border: 1px solid #CCC; +} + +.cart-buy { + display: block; + margin: 2px 4px; +} + +.cart-total { + position: absolute; + left: 5px; + bottom: 0px; +} + +.cart-toggle { + display: block; + color: #AAA; + text-decoration: none; + float: right; + padding: 0px 5px; +} +.cart-toggle:hover { + color: #555; +} diff --git a/plugins/shopping_cart/views/cart.html.erb b/plugins/shopping_cart/views/cart.html.erb new file mode 100644 index 0000000..a351768 --- /dev/null +++ b/plugins/shopping_cart/views/cart.html.erb @@ -0,0 +1,21 @@ + + + -- libgit2 0.21.2