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 @@ |
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> | ... | ... |