-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathshop.js
220 lines (189 loc) · 8.22 KB
/
shop.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
let productDetails = {};
let searchStr = "";
let basket = {};
//Each product is based on a 'card'; a box that contains information about that product.
//You can change the card template here. The [EVEGPRODUCT#] will always be subsituted for
//the element in the imagesArr (see fruit.js)
//The classes can be styled using CSS
//The adjustDown and adjustUp buttons have their behaviour specified below, but you can change this if you like
//To change the quantity of a product, change the value of the input (with the class of buyInput), you can then recalculate the basket with refreshBasket()
//Or you can adjust the basket object via javascript and call updateQuantityInputs() and refreshBasket()
var cardTemplate = `<div class="shop-product card" data-num="[EVEGPRODUCT#]">
<div class="shop-product-details shop-product-title card__title" data-field="title" data-num="[EVEGPRODUCT#]"></div>
<div class="card__content" data-num="[EVEGPRODUCT#]">
<div class="shop-product-details shop-product-img" data-field="img" data-num="[EVEGPRODUCT#]"></div>
<div class="shop-product-details shop-product-price" data-field="price" data-num="[EVEGPRODUCT#]"></div>
<div class="shop-product-details shop-product-units" data-field="units" data-num="[EVEGPRODUCT#]"></div>
<div class="shop-product-buying" data-num="[EVEGPRODUCT#]">
<div class="productBasketDiv"><button class="addToBasket">Add to Basket</button>
<div class="adjustDiv"><button class="btn adjustDown">-</button>
<input class="buyInput" data-num="[EVEGPRODUCT#]" min="0" value="0" type="number">
<button class="btn adjustUp">+</button></div></div></div></div></div>`;
function init(){
const toggleButton = document.getElementsByClassName('toggle-button')[0];
const hero = document.getElementsByClassName('hero')[0];
const navbarLinks = document.getElementsByClassName('navbar-links')[0];
//When the toggle button is pressed (if visible by the screen size, the menu is shown)
toggleButton.addEventListener('click',()=>{
navbarLinks.classList.toggle('active');
hero.classList.toggle('menuactive');
});
const searchBar = document.getElementsByClassName('search-bar')[0];
//Show the search bar when the search link is pressed
document.getElementById('search-link').addEventListener('click',()=>{
searchBar.classList.toggle('active');
document.getElementById('searchbox').focus();
});
//Close the search bar
document.getElementById('searchbutton').addEventListener('click', ()=>{
searchStr = document.getElementById('searchbox').value;
redraw();
});
//Close the search bar
document.getElementById('closesearchbutton').addEventListener('click', ()=>{
searchStr = "";
searchBar.classList.remove('active');
redraw();
});
//Close the cookies message
document.getElementById('acceptCookies').addEventListener('click', ()=>{
setCookie('cookieMessageSeen', true);
document.getElementById('cookieMessage').style.display = 'none';
});
if(getCookie("cookieMessageSeen") == "true"){
document.getElementById('cookieMessage').style.display = 'none';
}
initProducts(redraw);
}
/*
* When changing the page, you should make sure that each adjust button has exactly one click event
* (otherwise it might trigger multiple times)
* So this function loops through each adjustment button and removes any existing event listeners
* Then it adds another event listener
*/
function resetListeners(){
var elements = document.getElementsByClassName("adjustUp");
var eIn;
for(eIn = 0; eIn < elements.length; eIn++){
elements[eIn].removeEventListener("click",increment);
elements[eIn].addEventListener("click",increment);
}
elements = document.getElementsByClassName("adjustDown");
for(eIn = 0; eIn < elements.length; eIn++){
elements[eIn].removeEventListener("click",decrement);
elements[eIn].addEventListener("click",decrement);
}
elements = document.getElementsByClassName("buyInput");
for(eIn = 0; eIn < elements.length; eIn++){
elements[eIn].removeEventListener("change",inputchange);
elements[eIn].addEventListener("change",inputchange);
}
elements = document.getElementsByClassName("addToBasket");
for(eIn = 0; eIn < elements.length; eIn++){
elements[eIn].removeEventListener("click",increment);
elements[eIn].addEventListener("click",increment);
}
}
//When the input changes, add a 'bought' class if more than one is added
function inputchange(ev){
var thisID = ev.target.parentElement.closest(".card__content").getAttribute("data-num");
changeQuantity(thisID,ev.target.parentElement.closest(".shop-product-buying").getElementsByTagName("input")[0].value);
}
/*
* Change the quantity of the product with productID
*/
function changeQuantity(productID, newQuantity){
basket[productID] = newQuantity;
if(newQuantity == 0)
delete basket[productID];
document.querySelector(".buyInput[data-num='"+productID+"']").value = newQuantity;
refreshBasket();
}
//Add 1 to the quantity
function increment(ev){
var thisID = ev.target.parentElement.closest(".card__content").getAttribute("data-num");
if(basket[thisID] === undefined){
basket[thisID] = 0;
}
changeQuantity(thisID,parseInt(basket[thisID])+1);
}
//Subtract 1 from the quantity
function decrement(ev){
var thisID = ev.target.parentElement.closest(".card__content").getAttribute("data-num");
if(basket[thisID] === undefined){
changeQuantity(thisID,0);
}else{
if(basket[thisID] > 0){
changeQuantity(thisID,parseInt(basket[thisID])-1);
}
}
}
function filterFunction(a){
/*This demonstrates how to filter based on the search term*/
return a.name.toLowerCase().includes(searchStr.toLowerCase());
//If you wanted to just filter based on fruit/veg you could do something like this:
// return a.type == 'veg';
// return a.type == 'fruit';
// return true;
}
function sortFunction(a,b){
return a.price > b.price;
}
//Redraw all products based on the card template
function redraw(){
//Reset the product list (there are possibly more efficient ways of doing this, but this is simplest)
document.querySelector('.productList').innerHTML = '';
var shownProducts = productDetails.filter(filterFunction);
shownProducts.sort(sortFunction);
var numProducts = shownProducts.length;
for(var i = 0; i < numProducts; i++){
var cardHTML = cardTemplate.replaceAll("[EVEGPRODUCT#]",shownProducts[i].productID);
var thisProduct = document.createElement("div");
thisProduct.innerHTML = cardHTML;
document.querySelector('.productList').appendChild(thisProduct.firstChild);
}
document.querySelectorAll(".shop-product-details").forEach(function(element){
var field = element.getAttribute("data-field");
var num = element.getAttribute("data-num");
switch(field){
case "title":
element.innerText = productDetails[num].name;
break;
case "img":
element.innerHTML = "<span class=\"imgspacer\"></span><img src=\"images/"+productDetails[num].image + "\"></img>";
break;
case "price":
element.innerHTML = "<span>£"+(productDetails[num].price/100).toFixed(2)+"</span>";
break;
case "units":
element.innerHTML = "<span>"+productDetails[num].packsize + " " + productDetails[num].units+"</span>";
break;
}
});
resetListeners();
updateQuantityInputs();
}
window.addEventListener("load", init);
function updateQuantityInputs(){
for(let buyInput of document.querySelectorAll(".buyInput")){
let quantity = basket[buyInput.getAttribute("data-num")];
if(isNaN(quantity))
quantity = 0;
buyInput.value = quantity;
}
}
//Recalculate basket
function refreshBasket(){
let total = 0;
for(const productID in basket){
let quantity = basket[productID];
let price = productDetails[productID].price;
total = total + (price * quantity);
}
setCookie('basket', JSON.stringify(basket));
try{
document.querySelector("#basketNumTotal").innerHTML = (total / 100).toFixed(2);
}catch(e){
}
return total;
}