Commit f2de59354a21fe42ee89921d5de4960d8800bdcf
1 parent
77496dba
Exists in
staging
and in
42 other branches
JS, CSS and HTML.
Don't panic! =D
Showing
3 changed files
with
373 additions
and
0 deletions
Show diff stats
| ... | ... | @@ -0,0 +1,246 @@ |
| 1 | +function Cart(config) { | |
| 2 | + var $ = jQuery; | |
| 3 | + Cart.instance = this; // this may be a list on the future; | |
| 4 | + this.cartElem = $("#cart1")[0]; | |
| 5 | + this.cartElem.cartObj = this; | |
| 6 | + this.contentBox = $("#cart1 .cart-content"); | |
| 7 | + this.itemsBox = $("#cart1 .cart-items"); | |
| 8 | + this.items = {}; | |
| 9 | + this.visible = false; | |
| 10 | + if (config.hasProducts) { | |
| 11 | + $(this.cartElem).show(); | |
| 12 | + this.enterprise = config.enterprise; | |
| 13 | + this.listProducts(); | |
| 14 | + } | |
| 15 | + $(".cart-buy", this.cartElem).button({ icons: { primary: 'ui-icon-cart'} }); | |
| 16 | +} | |
| 17 | + | |
| 18 | +(function($){ | |
| 19 | + | |
| 20 | + Cart.prototype.listProducts = function() { | |
| 21 | + var me = this; | |
| 22 | + $.ajax({ | |
| 23 | + url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/list', | |
| 24 | + dataType: 'json', | |
| 25 | + success: function(data, ststus, ajax){ | |
| 26 | + if ( !data.ok ) alert(data.error.message); | |
| 27 | + else me.addToList(data, true); | |
| 28 | + }, | |
| 29 | + cache: false, | |
| 30 | + error: function(ajax, status, errorThrown) { | |
| 31 | + alert('List cart items - HTTP '+status+': '+errorThrown); | |
| 32 | + } | |
| 33 | + }); | |
| 34 | + } | |
| 35 | + | |
| 36 | + Cart.prototype.addToList = function(data, clear) { | |
| 37 | + if( clear ) this.itemsBox.empty(); | |
| 38 | + var me = this; | |
| 39 | + for( var item,i=0; item=data.products[i]; i++ ) { | |
| 40 | + this.items[item.id] = { price:item.price, quantity:item.quantity }; | |
| 41 | + this.updateTotal(); | |
| 42 | + var liId = "cart-item-"+item.id; | |
| 43 | + var li = $("#"+liId); | |
| 44 | + if( !li[0] ) li = $('<li id="'+liId+'"></li>\n').appendTo(this.itemsBox); | |
| 45 | + li.empty(); | |
| 46 | + $('<div class="picture" style="background-image:url('+item.picture+')"></div>' + | |
| 47 | + '<span class="item-name">'+ item.name +'</span>' + | |
| 48 | + '<div class="item-price">' + | |
| 49 | + '<input size="1" value="'+item.quantity+'" />'+ (item.price ? '× '+ item.price : '') +'</div>' + | |
| 50 | + ' <a href="remove:'+item.name+'" onclick="Cart.removeItem(\''+this.enterprise+'\', '+item.id+'); return false"' + | |
| 51 | + ' class="button icon-delete"><span>remove</span></a>' | |
| 52 | + ).appendTo(li); | |
| 53 | + var input = $("input", li)[0]; | |
| 54 | + input.lastValue = input.value; | |
| 55 | + input.itemId = item.id; | |
| 56 | + input.ajustSize = function() { | |
| 57 | + var len = this.value.toString().length; | |
| 58 | + if(len > 2) len--; | |
| 59 | + this.style.width = len+"em"; | |
| 60 | + }; | |
| 61 | + input.ajustSize(); | |
| 62 | + input.onchange = function() { | |
| 63 | + me.updateQuantity(this, this.itemId, this.value); | |
| 64 | + }; | |
| 65 | + document.location.href = "#"+liId; | |
| 66 | + document.location.href = "#"+this.cartElem.id; | |
| 67 | + history.go(-2); | |
| 68 | + var liBg = li.css("background-color"); | |
| 69 | + li[0].style.backgroundColor = "#FF0"; | |
| 70 | + li.animate({ backgroundColor: liBg }, 1000); | |
| 71 | + } | |
| 72 | + if( !this.visible ) { | |
| 73 | + this.contentBox.hide(); | |
| 74 | + this.show(); | |
| 75 | + } | |
| 76 | + } | |
| 77 | + | |
| 78 | + Cart.prototype.updateQuantity = function(input, itemId, quantity) { | |
| 79 | + quantity = parseInt(quantity); | |
| 80 | + input.disabled = true; | |
| 81 | + var originalBg = input.style.backgroundImage; | |
| 82 | + input.style.backgroundImage = "url(/images/loading-small.gif)"; | |
| 83 | + var me = this; | |
| 84 | + if( quantity == NaN ) return input.value = input.lastValue; | |
| 85 | + $.ajax({ | |
| 86 | + url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/update_quantity/'+ itemId +'?quantity='+ quantity, | |
| 87 | + dataType: 'json', | |
| 88 | + success: function(data, status, ajax){ | |
| 89 | + if ( !data.ok ) { | |
| 90 | + alert(data.error.message); | |
| 91 | + input.value = input.lastValue; | |
| 92 | + } | |
| 93 | + else { | |
| 94 | + input.lastValue = quantity; | |
| 95 | + me.items[itemId].quantity = quantity; | |
| 96 | + me.updateTotal(); | |
| 97 | + } | |
| 98 | + }, | |
| 99 | + cache: false, | |
| 100 | + error: function(ajax, status, errorThrown) { | |
| 101 | + alert('Add item - HTTP '+status+': '+errorThrown); | |
| 102 | + input.value = input.lastValue; | |
| 103 | + }, | |
| 104 | + complete: function(){ | |
| 105 | + input.disabled = false; | |
| 106 | + input.style.backgroundImage = originalBg; | |
| 107 | + input.ajustSize(); | |
| 108 | + } | |
| 109 | + }); | |
| 110 | + } | |
| 111 | + | |
| 112 | + Cart.prototype.removeFromList = function(itemId) { | |
| 113 | + $("#cart-item-"+itemId).slideUp(500, function() {$(this).remove()}); | |
| 114 | + delete this.items[itemId]; | |
| 115 | + this.updateTotal(); | |
| 116 | + } | |
| 117 | + | |
| 118 | + Cart.addItem = function(enterprise, itemId, link) { | |
| 119 | + // on the future, the instance may be found by the enterprise identifier. | |
| 120 | + link.intervalId = setInterval(function() { | |
| 121 | + steps = ['w', 'n', 'e', 's']; | |
| 122 | + if( !link.step || link.step==3 ) link.step = 0; | |
| 123 | + link.step++; | |
| 124 | + $(link).button({ icons: { primary: 'ui-icon-arrowrefresh-1-'+steps[link.step]}, disable: true }) | |
| 125 | + }, 100); | |
| 126 | + var stopBtLoading = function() { | |
| 127 | + clearInterval(link.intervalId); | |
| 128 | + $(link).button({ icons: { primary: 'ui-icon-cart'}, disable: false }); | |
| 129 | + }; | |
| 130 | + this.instance.addItem(enterprise, itemId, stopBtLoading); | |
| 131 | + } | |
| 132 | + | |
| 133 | + Cart.prototype.addItem = function(enterprise, itemId, callback) { | |
| 134 | + if(!this.enterprise) { | |
| 135 | + this.enterprise = enterprise; | |
| 136 | + if( !this.visible ) $(this.cartElem).show(); | |
| 137 | + } | |
| 138 | + var me = this; | |
| 139 | + $.ajax({ | |
| 140 | + url: '/profile/'+ enterprise +'/plugins/shopping_cart/add/'+ itemId, | |
| 141 | + dataType: 'json', | |
| 142 | + success: function(data, status, ajax){ | |
| 143 | + if ( !data.ok ) alert(data.error.message); | |
| 144 | + else me.addToList(data); | |
| 145 | + }, | |
| 146 | + cache: false, | |
| 147 | + error: function(ajax, status, errorThrown) { | |
| 148 | + alert('Add item - HTTP '+status+': '+errorThrown); | |
| 149 | + }, | |
| 150 | + complete: callback | |
| 151 | + }); | |
| 152 | + } | |
| 153 | + | |
| 154 | + Cart.removeItem = function(enterprise, itemId) { | |
| 155 | + var message = this.instance.cartElem.getAttribute('data-l10nRemoveItem'); | |
| 156 | + if( confirm(message) ) this.instance.removeItem(enterprise, itemId); | |
| 157 | + } | |
| 158 | + | |
| 159 | + Cart.prototype.removeItem = function(enterprise, itemId) { | |
| 160 | + if ($("li", this.itemsBox).size() < 2) return this.clean(); | |
| 161 | + var me = this; | |
| 162 | + $.ajax({ | |
| 163 | + url: '/profile/'+ enterprise +'/plugins/shopping_cart/remove/'+ itemId, | |
| 164 | + dataType: 'json', | |
| 165 | + success: function(data, status, ajax){ | |
| 166 | + if ( !data.ok ) alert(data.error.message); | |
| 167 | + else me.removeFromList(data.product_id); | |
| 168 | + }, | |
| 169 | + cache: false, | |
| 170 | + error: function(ajax, status, errorThrown) { | |
| 171 | + alert('Remove item - HTTP '+status+': '+errorThrown); | |
| 172 | + } | |
| 173 | + }); | |
| 174 | + } | |
| 175 | + | |
| 176 | + Cart.toggle = function(link) { | |
| 177 | + link.parentNode.parentNode.cartObj.toggle(); | |
| 178 | + } | |
| 179 | + Cart.prototype.toggle = function() { | |
| 180 | + this.visible ? this.hide() : this.show(); | |
| 181 | + } | |
| 182 | + | |
| 183 | + Cart.prototype.show = function() { | |
| 184 | + this.visible = true; | |
| 185 | + this.contentBox.slideDown(500); | |
| 186 | + $(".cart-toggle .str-show", this.cartElem).hide(); | |
| 187 | + $(".cart-toggle .str-hide", this.cartElem).show(); | |
| 188 | + | |
| 189 | + } | |
| 190 | + Cart.prototype.hide = function() { | |
| 191 | + this.visible = false; | |
| 192 | + this.contentBox.slideUp(500); | |
| 193 | + $(".cart-toggle .str-show", this.cartElem).show(); | |
| 194 | + $(".cart-toggle .str-hide", this.cartElem).hide(); | |
| 195 | + } | |
| 196 | + | |
| 197 | + Cart.prototype.updateTotal = function() { | |
| 198 | + var total = 0; | |
| 199 | + var currency, sep = ""; | |
| 200 | + for( var itemId in this.items ) { | |
| 201 | + var item = this.items[itemId]; | |
| 202 | + if( item.price ) { | |
| 203 | + currency = item.price.replace(/^([^0-9]+).*$/, "$1"); | |
| 204 | + sep = item.price.charAt(item.price.length-3); | |
| 205 | + var price = item.price.replace(/[^0-9]/g,""); | |
| 206 | + total += item.quantity * parseFloat(price); | |
| 207 | + } | |
| 208 | + } | |
| 209 | + total = Math.round(total).toString().replace(/(..)$/, sep+"$1") | |
| 210 | + $(".cart-total b", this.cartElem).text( ( (total!=0) ? currency+" "+total : "---" ) ); | |
| 211 | + } | |
| 212 | + | |
| 213 | + Cart.clean = function(link) { | |
| 214 | + var message = this.instance.cartElem.getAttribute('data-l10nCleanCart'); | |
| 215 | + if( confirm(message) ) link.parentNode.parentNode.parentNode.cartObj.clean(); | |
| 216 | + } | |
| 217 | + | |
| 218 | + Cart.prototype.clean = function() { | |
| 219 | + var me = this; | |
| 220 | + $.ajax({ | |
| 221 | + url: '/profile/'+ me.enterprise +'/plugins/shopping_cart/clean', | |
| 222 | + dataType: 'json', | |
| 223 | + success: function(data, status, ajax){ | |
| 224 | + if ( !data.ok ) alert(data.error.message); | |
| 225 | + else{ | |
| 226 | + me.items = {}; | |
| 227 | + $(me.cartElem).slideUp(500, function() { | |
| 228 | + $(me.itemsBox).empty(); | |
| 229 | + me.hide(); | |
| 230 | + me.enterprise = null; | |
| 231 | + me.updateTotal(); | |
| 232 | + }); | |
| 233 | + } | |
| 234 | + }, | |
| 235 | + cache: false, | |
| 236 | + error: function(ajax, status, errorThrown) { | |
| 237 | + alert('Remove item - HTTP '+status+': '+errorThrown); | |
| 238 | + } | |
| 239 | + }); | |
| 240 | + } | |
| 241 | + | |
| 242 | + $(function(){ | |
| 243 | + $('.cart-add-item').button({ icons: { primary: 'ui-icon-cart'} }) | |
| 244 | + }); | |
| 245 | + | |
| 246 | +})(jQuery); | ... | ... |
| ... | ... | @@ -0,0 +1,106 @@ |
| 1 | +.cart-add-item { | |
| 2 | + position: absolute; | |
| 3 | + right: 5px; | |
| 4 | + top: 5px; | |
| 5 | +} | |
| 6 | + | |
| 7 | +.cart { | |
| 8 | + position: absolute; | |
| 9 | + right: 20px; | |
| 10 | + top: 0px; | |
| 11 | + width: 200px; | |
| 12 | + z-index: 1000; | |
| 13 | + border: 1px solid #777; | |
| 14 | + border-top: none; | |
| 15 | + background: rgba(200,200,200,0.6); | |
| 16 | +} | |
| 17 | + | |
| 18 | +.cart h3 { | |
| 19 | + color: #888; | |
| 20 | + margin: 0px 0px 0px 5px; | |
| 21 | +} | |
| 22 | + | |
| 23 | +.cart-clean { | |
| 24 | + color: #AAA; | |
| 25 | + position: absolute; | |
| 26 | + top: 1px; | |
| 27 | + right: 5px; | |
| 28 | + text-decoration: none; | |
| 29 | +} | |
| 30 | +.cart-clean:hover { | |
| 31 | + color: #888; | |
| 32 | +} | |
| 33 | + | |
| 34 | +.cart-content { | |
| 35 | + display: none; | |
| 36 | +} | |
| 37 | + | |
| 38 | +.cart-items { | |
| 39 | + margin: 0px; | |
| 40 | + padding: 0px; | |
| 41 | + max-height: 328px; | |
| 42 | + overflow: auto; | |
| 43 | +} | |
| 44 | + | |
| 45 | +.cart-items li { | |
| 46 | + height: 50px; | |
| 47 | + padding: 5px; | |
| 48 | + margin: 3px; | |
| 49 | + border: 1px solid #999; | |
| 50 | + list-style: none; | |
| 51 | + background: #FFF; | |
| 52 | + position: relative; | |
| 53 | +} | |
| 54 | + | |
| 55 | +.cart-items .picture { | |
| 56 | + float: left; | |
| 57 | + width: 50px; | |
| 58 | + height: 50px; | |
| 59 | + margin-right: 10px; | |
| 60 | + background-repeat: no-repeat; | |
| 61 | + background-position: 50% 50%; | |
| 62 | +} | |
| 63 | + | |
| 64 | +.cart .item-name { | |
| 65 | + margin-right: 20px; | |
| 66 | +} | |
| 67 | + | |
| 68 | +.cart .button { | |
| 69 | + position: absolute; | |
| 70 | + top: 2px; | |
| 71 | + right: 2px; | |
| 72 | +} | |
| 73 | + | |
| 74 | +.cart input { | |
| 75 | + border: 1px solid transparent; | |
| 76 | + background: transparent 50% 50% no-repeat; | |
| 77 | + text-align: center; | |
| 78 | + padding: 0px; | |
| 79 | + font-family: monospace; | |
| 80 | + width: 2em; | |
| 81 | +} | |
| 82 | +.cart:hover input, .cart input:focus { | |
| 83 | + border: 1px solid #CCC; | |
| 84 | +} | |
| 85 | + | |
| 86 | +.cart-buy { | |
| 87 | + display: block; | |
| 88 | + margin: 2px 4px; | |
| 89 | +} | |
| 90 | + | |
| 91 | +.cart-total { | |
| 92 | + position: absolute; | |
| 93 | + left: 5px; | |
| 94 | + bottom: 0px; | |
| 95 | +} | |
| 96 | + | |
| 97 | +.cart-toggle { | |
| 98 | + display: block; | |
| 99 | + color: #AAA; | |
| 100 | + text-decoration: none; | |
| 101 | + float: right; | |
| 102 | + padding: 0px 5px; | |
| 103 | +} | |
| 104 | +.cart-toggle:hover { | |
| 105 | + color: #555; | |
| 106 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | +<div id="cart1" class="cart" style="display:none" | |
| 2 | + data-l10nRemoveItem="<%=_('Are you sure you want to remove this item?')%>" | |
| 3 | + data-l10nCleanCart="<%=_('Are you sure you want to clean your cart?')%>"> | |
| 4 | + <div class="cart-inner"> | |
| 5 | + <div class="cart-content"> | |
| 6 | + <h3><%= _("Cart") %></h3> | |
| 7 | + <a href="cart:clean" onclick="Cart.clean(this); return false" class="cart-clean"><%=_('Clean cart')%></a> | |
| 8 | + <ul class="cart-items"></ul> | |
| 9 | + <div class="cart-total"><%=_('Total:')%> <b></b></div> | |
| 10 | + <a href="cart:buy" class="cart-buy" onclick="alert('foi mô pai!'); return false"><%=_('Shopping checkout')%></a> | |
| 11 | + </div> | |
| 12 | + <a href="#" onclick="Cart.toggle(this); return false" class="cart-toggle"> | |
| 13 | + <span class="str-show"><%=_('Show cart')%></span> | |
| 14 | + <span class="str-hide" style="display:none"><%=_('Hide cart')%></span> | |
| 15 | + </a> | |
| 16 | + </div> | |
| 17 | +</div> | |
| 18 | + | |
| 19 | +<script type="text/javascript"> | |
| 20 | + new Cart({hasProducts:<%= !locals[:cart].nil? ? "true, enterprise:'#{Enterprise.find(locals[:cart][:enterprise_id]).identifier}'" : "false" %>}); | |
| 21 | +</script> | ... | ... |