Commit f2de59354a21fe42ee89921d5de4960d8800bdcf
1 parent
77496dba
Exists in
master
and in
29 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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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> |