Add or remove a value from a localstorage object - javascript

I want add or remove 1 by click for one of the obj.onlist in this array from localstorage
{loklakchicken: {name: "Lok Lak Chicken", tag: "loklakchicken", price: 9.9, onList: 2},…}
Lottchabeef: {name: "Lot Tcha Beef", tag: "Lottchabeef", price: 9.9, onList: 1}
loklakchicken: {name: "Lok Lak Chicken", tag: "loklakchicken", price: 9.9, onList: 2}
loklakvegan: {name: "Lok Lak Vegan", tag: "loklakvegan", price: 9.9, onList: 17}
lottchavegan: {name: "Lot Tcha Vegan", tag: "lottchavegan", price: 9.9, onList: 2}
I try something like this
let obj = localStorage.getItem('prodOnList');
obj = JSON.parse(orderListItems);
for (let i = 0; i < obj.length; i++) {
$('.plus').click(function () {
obj[i].onList += 1;
}
$('.minus').click(function () {
obj[i].onList -= 1;
}
}
localStorage.setItem("prodOnList", JSON.stringify(obj));
I am sure i am missing something pretty obvious, thx
UPDATE
I am doing a cart list create with JS and for each product on the list I have a button to add or remove one...
I try to bind my function setItems on btn plus click event no result...
My problem is i dont now how to target the object from the array on localstorage where i am calling the event click!
thx for your help
class OrderBtn{
constructor(){
this.prodList = [
just remove the array with the products
];
}
addToList(){
let menus = document.querySelectorAll('.add-list');
for (let i = 0; i < menus.length; i++) {
$(menus[i]).click(()=>{
this.listCount(this.prodList[i]);
this.totalPrice(this.prodList[i]);
this.displayOrderList();
});
}
}
listCount(prod){
let productNum = localStorage.getItem('listNum');
productNum = parseInt(productNum);
if (productNum) {
localStorage.setItem('listNum', productNum + 1);
} else {
localStorage.setItem('listNum', 1);
}
this.setItems(prod);
}
setItems(prod){
let orderListItems = localStorage.getItem('prodOnList');
orderListItems = JSON.parse(orderListItems);
if (orderListItems !== null){
if(orderListItems[prod.tag] === undefined){
orderListItems = {
...orderListItems,
[prod.tag]: prod
}
}
orderListItems[prod.tag].onList += 1;
} else{
prod.onList = 1;
orderListItems = {
[prod.tag]: prod
}
}
localStorage.setItem("prodOnList", JSON.stringify(orderListItems));
}
totalPrice(prod){
let orderTotal = localStorage.getItem('totalCost');
if(orderTotal !== null){
orderTotal = parseFloat(orderTotal);
let resultPrice = orderTotal + prod.price;
resultPrice = resultPrice.toFixed(2);
localStorage.setItem('totalCost', resultPrice);
} else {
localStorage.setItem('totalCost', prod.price.toFixed(2));
}
}
displayOrderList(){
let orderItems = localStorage.getItem('prodOnList');
let orderTotal = localStorage.getItem('totalCost');
orderItems = JSON.parse(orderItems);
let orderContainer = document.querySelector('.orderList');
if (orderItems && orderContainer) {
orderContainer.innerHTML = "";
Object.values(orderItems).map(item =>{
let totalItem = item.onList * item.price;
totalItem = totalItem.toFixed(2);
orderContainer.innerHTML += `
<div class="quantity d-flex justify-content-between align-items-center mb-2">
<i class="fas fa-times text-danger"></i>
<div class="itemNum">
<i class="btnMinus fas fa-minus"></i>
<span class="mx-2">${item.onList}</span>
<i class="btnPlus fas fa-plus"></i>
</div>
<span class="total">${totalItem} €</span>
</div>
<div class="product d-flex justify-content-between align-items-center">
<span>${item.name}</span>
</div>
`;
});
$('.totalOrder').text(`Total : ${orderTotal} €`)
}else{
orderContainer.innerHTML = `
<p class="product">Votre panier est vide</p>`;
$('.totalOrder').text(`Total : 0.00 €`)
}
}
}

If I didn't misunderstood your problem, this will work for you
$('.plus').click(function () {
addOrRemoveByOne('add');
}
$('.minus').click(function () {
addOrRemoveByOne('remove');
}
addOrRemoveByOne(option) {
let obj = JSON.parse(localStorage.getItem('prodOnList'));
for (let key in obj) {
if (option === 'add') {
obj[key].onList += 1;
}
if (option === 'remove') {
obj[key].onList -= 1;
}
}
localStorage.setItem("prodOnList", JSON.stringify(obj));}
}

Related

Star Rating based on Avg. Number - Vanilla JS

I can't seem to find the solution.
I need only to display the stars, based on the fixed average number. So half star for a decimal above 0.5, while star for an integer and outline star for a value below 0.5.
Based on the data
const shirt = {
name: "White Shirt",
newPrice: 10.99,
oldPrice: 29.99,
avgRating: 4.3
}
const productDetail = document.querySelector('.product-detail')
productDetail.innerHTML = `
<h2>${shirt.name}</h2>
<div class="sale-perc">
<span>33% OFF</span>
</div>
<div class="price-review">
<div class="price">
<span class="new-price">${shirt.newPrice}</span>
<span class="old-price">${shirt.oldPrice}</span>
</div>
<div class="review-rating">
<div class="review-stars">
<p>
${(() => {
let rating = ''
const avgRating = shirt.avgRating
for (let i = 0; i < 5; i++) {
if (i < avgRating) {
rating += `<i class="fa-solid fa-star"></i>`
} else if (i === avgRating && avgRating % 1 !== 0) {
rating += `<i class="fa-solid fa-star-half-alt"></i>`
} else {
rating += `<i class="fa-regular fa-star"></i>`
}
}
return rating
})()}
</p>
</div>
</div>
</div>
let rating = ''
const avgRating = shirt.avgRating
for (let i = 1; i <= avgRating; i += 0.5) {
if (i % 1 === 0) {
rating += `<i class="fa-solid fa-star"></i>`;
} else if (i % 1 !== 0 && i === avgRating) {
rating += `<i class="fa-solid fa-star-half-alt"></i>`;
}
}
return rating;

Shopping Cart Update Total Function doesnt work

I am building an eCommerce store website, and I am facing an issue. The function updateCartTotal doesn't work at all. The script is also added to the bottom of the HTML body.
Thanks in advance.
HTML:
<span class="material-symbols-outlined" id="cart-icon">
shopping_cart
</span>
<div class="cart">
<h2 class="cart-title">Your Shopping Cart</h2>
<div class="cart-content">
<div class="cart-box">
<img src="/Monn-Homme/images/tie1.jpg" class="cart-image">
<div class="detail-box">
<div class="cart-product-title">
Tie
</div>
<div class="cart-price"> £10.99</div>
<input type="number" value="1" class="cart-qty">
</div>
<span class="material-symbols-outlined" id="cart-remove">
delete
</span>
</div>
</div>
<div class="total">
<div class="total-title">Total</div>
<div class="total-price">£10.99</div>
</div>
<button type="button" class="buy-btn">Buy Now</button>
<span class="material-symbols-outlined" id="close-cart">
close
</span>
</div>
</div>
Javascript:
let cartIcon = document.getElementById("cart-icon");
let cart = document.querySelector(".cart");
let CloseCart = document.querySelector("#close-cart");
cartIcon.onclick = () => {
cart.classList.add("active");
};
CloseCart.onclick = () => {
cart.classList.remove("active");
};
if (document.readyState == "loading") {
document.addEventListener("DOMContentLoaded", ready);
} else {
ready();
}
function ready() {
var removeCartButtons = document.getElementsByClassName("material-symbols-outlined");
for (var i = 0; i < removeCartButtons.length; i++) {
var button = removeCartButtons[i];
button.addEventListener("click", removeCartItem)
}
// Quantity Change //
var quantitInputs = document.getElementsByClassName("cart qty");
for (var i = 0; i < quantitInputs.length; i++) {
var input = quantitInputs[i];
input.addEventListener("change", quantityChanged);
}
}
function removeCartItem(event) {
var buttonClicked = event.target;
buttonClicked.parentElement.remove();
updateCartTotal();
}
quantityChanged = (event) => {
var input = event.target;
if (isNaN(input.value) || input.value <= 0) {
input.value = 1;
}
updateCartTotal();
}
function updateCartTotal() {
var cartContainer = document.getElementsByClassName("cart-content")[0];
var cartBox = cartContainer.getElementsByClassName("cart-box");
var total = 0
for (var i = 0; i < cartBox.length; i++) {
var cartBox = cartBox[i]
var priceElement = cartBox.getElementsByClassName("cart-price")[0]
var quantityElement = cartBox.getElementsByClassName("cart-qty")[0]
price = parseFloat(priceElement.innerText.replace("£", ""))
quantity = quantityElement.value
total = total + (price * quantity)
}
document.getElementsByClassName("total-price")[0].innerText = total
}
i am expecting the total to update as the quantity changes, and the function to work
You have the following mistakes-
There is no element with the class name cart qty.
var quantitInputs = document.getElementsByClassName("cart qty");
quantityChanged function should have a function keyword.
You are using the same name variable cartBox in updateCartTotal function which is creating confusion-
var cartBox = cartContainer.getElementsByClassName("cart-box");
for (var i = 0; i < cartBox.length; i++) {
var cartBox = cartBox[i]
}
Now, after fixing these mistakes, your code will look like the below which is working.
Note- I moved all the declarations to the top and I replaced those two methods-
getElementsByClassName() = querySelectorAll()
getElementsByClassName()[0] = querySelector()
let cartIcon = document.querySelector("#cart-icon");
let cart = document.querySelector(".cart");
let CloseCart = document.querySelector("#close-cart");
var quantitInputs = document.querySelectorAll(".cart-qty");
var removeCartButtons = document.querySelectorAll(".material-symbols-outlined");
var cartContainer = document.querySelector(".cart-content");
var cartBox = cartContainer.querySelectorAll(".cart-box");
var totalEl = document.querySelector(".total-price")
cartIcon.onclick = () => {
cart.classList.add("active");
};
CloseCart.onclick = () => {
cart.classList.remove("active");
};
if (document.readyState == "loading") {
document.addEventListener("DOMContentLoaded", ready);
} else {
ready();
}
function ready() {
for (var i = 0; i < removeCartButtons.length; i++) {
var button = removeCartButtons[i];
button.addEventListener("click", removeCartItem);
}
// Quantity Change //
for (var i = 0; i < quantitInputs.length; i++) {
var input = quantitInputs[i];
input.addEventListener("change", quantityChanged);
}
}
function removeCartItem(event) {
var buttonClicked = event.target;
buttonClicked.parentElement.remove();
updateCartTotal();
}
function quantityChanged(event) {
var input = event.target;
if (isNaN(input.value) || input.value <= 0) {
input.value = 1;
}
updateCartTotal();
};
function updateCartTotal() {
var total = 0;
for (var i = 0; i < cartBox.length; i++) {
var cartBoxEl = cartBox[i];
var priceElement = cartBoxEl.querySelector(".cart-price");
var quantityElement = cartBoxEl.querySelector(".cart-qty");
price = parseFloat(priceElement.innerText.replace("£", ""));
quantity = quantityElement.value;
total = total + price * quantity;
}
if (totalEl) {
totalEl.innerText = total;
}
}
<div>
<span class="material-symbols-outlined" id="cart-icon">
shopping_cart
</span>
<div class="cart">
<h2 class="cart-title">Your Shopping Cart</h2>
<div class="cart-content">
<div class="cart-box">
<img src="/Monn-Homme/images/tie1.jpg" class="cart-image">
<div class="detail-box">
<div class="cart-product-title">
Tie
</div>
<div class="cart-price"> £10.99</div>
<input type="number" value="1" class="cart-qty">
</div>
<span class="material-symbols-outlined" id="cart-remove">
delete
</span>
</div>
</div>
<div class="total">
<div class="total-title">Total</div>
<div class="total-price">£10.99</div>
</div>
<button type="button" class="buy-btn">Buy Now</button>
<span class="material-symbols-outlined" id="close-cart">
close
</span>
</div>
</div>

'Remove item from cart' and 'manage Quantity' buttons not working when i add more products

I am designing an e-commerce website and since I am not good at DOM manipulation using Javascript so to add Cart functionality to the website I just copied some code from Github. All things are working fine, when I am adding a product it is added to the cart and when I click the remove button or try to increase or decrease the quantity of the product it works fine. The only problem is that when I try to add more products to the products section. The remove buttons and increase/decrease quantity buttons stop working. Can anyone please help me with this?
The Products in the products.html file look something like this.
<div class="image">
<img src="../images/greytshirt.jpg" alt="thsirt1">
<h3>
<ion-icon name="star"></ion-icon>
<ion-icon name="star"></ion-icon>
<ion-icon name="star"></ion-icon>
<ion-icon name="star"></ion-icon>
<ion-icon name="star-outline"></ion-icon>
</h3>
<h3>Grey Tshirt
</h3>
<h3>$15,00</h3>
<a class="add-cart cart1" href="#">Add to Cart</a>
<input type="hidden" value="15"/>
</div>
<div class="image">
<img src="../images/greyhoddie.jpg" alt="thsirt1">
<h3>
<ion-icon name="star"></ion-icon>
<ion-icon name="star"></ion-icon>
<ion-icon name="star"></ion-icon>
<ion-icon name="star-half"></ion-icon>
</h3>
<h3>Grey Hoddie</h3>
<h3>$20,00</h3>
<a class="add-cart cart2" href="#">Add to Cart</a>
<input type="hidden" value="20"/>
</div>
Main.js file(All functions are implemented in this file)
/*------------------------------------------------Js for cart related functionalities------------------------------------------------*/
let carts = document.querySelectorAll('.add-cart');
let products = [
{
name: "Grey Tshirt",
tag: "greytshirt",
price: 15,
inCart: 0
},
{
name: "Grey Hoddie",
tag: "greyhoddie",
price: 20,
inCart: 0
},
{
name: "Black Tshirt",
tag: "blacktshirt",
price: 15,
inCart: 0
},
{
name: "Black Hoddie",
tag: "blackhoddie",
price: 20,
inCart: 0
}
];
for(let i=0; i< carts.length; i++) {
carts[i].addEventListener('click', () => {
console.log(products[i]);
cartNumbers(products[i]);
totalCost(products[i]);
});
}
function onLoadCartNumbers() {
let productNumbers = localStorage.getItem('cartNumbers');
if( productNumbers ) {
document.querySelector('.cart span').textContent = productNumbers;
}
}
function cartNumbers(product, action) {
let productNumbers = localStorage.getItem('cartNumbers');
productNumbers = parseInt(productNumbers);
let cartItems = localStorage.getItem('productsInCart');
cartItems = JSON.parse(cartItems);
if( action ) {
localStorage.setItem("cartNumbers", productNumbers - 1);
document.querySelector('.cart span').textContent = productNumbers - 1;
console.log("action running");
} else if( productNumbers ) {
localStorage.setItem("cartNumbers", productNumbers + 1);
document.querySelector('.cart span').textContent = productNumbers + 1;
} else {
localStorage.setItem("cartNumbers", 1);
document.querySelector('.cart span').textContent = 1;
}
setItems(product);
}
function setItems(product) {
// let productNumbers = localStorage.getItem('cartNumbers');
// productNumbers = parseInt(productNumbers);
let cartItems = localStorage.getItem('productsInCart');
cartItems = JSON.parse(cartItems);
if(cartItems != null) {
let currentProduct = product.tag;
if( cartItems[currentProduct] == undefined ) {
cartItems = {
...cartItems,
[currentProduct]: product
}
}
cartItems[currentProduct].inCart += 1;
} else {
product.inCart = 1;
cartItems = {
[product.tag]: product
};
}
localStorage.setItem('productsInCart', JSON.stringify(cartItems));
}
function totalCost( product, action ) {
let cart = localStorage.getItem("totalCost");
if( action) {
cart = parseInt(cart);
localStorage.setItem("totalCost", cart - product.price);
} else if(cart != null) {
cart = parseInt(cart);
localStorage.setItem("totalCost", cart + product.price);
} else {
localStorage.setItem("totalCost", product.price);
}
}
function displayCart() {
let cartItems = localStorage.getItem('productsInCart');
cartItems = JSON.parse(cartItems);
let cart = localStorage.getItem("totalCost");
cart = parseInt(cart);
let productContainer = document.querySelector('.products');
if( cartItems && productContainer ) {
productContainer.innerHTML = '';
Object.values(cartItems).map( (item, index) => {
productContainer.innerHTML +=
`<div class="product"><ion-icon name="close-circle"></ion-icon><img src="../images/${item.tag}.jpg" />
<span class="sm-hide">${item.name}</span>
</div>
<div class="price sm-hide">$${item.price},00</div>
<div class="quantity">
<ion-icon class="decrease " name="arrow-dropleft-circle"></ion-icon>
<span>${item.inCart}</span>
<ion-icon class="increase" name="arrow-dropright-circle"></ion-icon>
</div>
<div class="total">$${item.inCart * item.price},00</div>`;
});
productContainer.innerHTML += `
<div class="basketTotalContainer">
<h4 class="basketTotalTitle">Basket Total</h4>
<h4 class="basketTotal">$${cart},00</h4>
<input class="empty" onclick="emptyCart()" value="Empty Cart">
</div>
<div class="checkout"><button class="placeorder btn" onclick="checkout()">Place Order</button></div>`
deleteButtons();
manageQuantity();
}
}
function manageQuantity() {
let decreaseButtons = document.querySelectorAll('.decrease');
let increaseButtons = document.querySelectorAll('.increase');
let currentQuantity = 0;
let currentProduct = '';
let cartItems = localStorage.getItem('productsInCart');
cartItems = JSON.parse(cartItems);
for(let i=0; i < increaseButtons.length; i++) {
decreaseButtons[i].addEventListener('click', () => {
currentQuantity = decreaseButtons[i].parentElement.querySelector('span').textContent;
currentProduct = decreaseButtons[i].parentElement.previousElementSibling.previousElementSibling.querySelector('span').textContent.toLocaleLowerCase().replace(/ /g,'').trim();
if( cartItems[currentProduct].inCart > 1 ) {
cartItems[currentProduct].inCart -= 1;
cartNumbers(cartItems[currentProduct], "decrease");
totalCost(cartItems[currentProduct], "decrease");
localStorage.setItem('productsInCart', JSON.stringify(cartItems));
displayCart();
}
});
increaseButtons[i].addEventListener('click', () => {
currentQuantity = increaseButtons[i].parentElement.querySelector('span').textContent;
currentProduct = increaseButtons[i].parentElement.previousElementSibling.previousElementSibling.querySelector('span').textContent.toLocaleLowerCase().replace(/ /g,'').trim();
cartItems[currentProduct].inCart += 1;
cartNumbers(cartItems[currentProduct]);
totalCost(cartItems[currentProduct]);
localStorage.setItem('productsInCart', JSON.stringify(cartItems));
displayCart();
});
}
}
function deleteButtons() {
let deleteButtons = document.querySelectorAll('.product ion-icon');
let productNumbers = localStorage.getItem('cartNumbers');
let cartCost = localStorage.getItem("totalCost");
let cartItems = localStorage.getItem('productsInCart');
cartItems = JSON.parse(cartItems);
let productName;
for(let i=0; i < deleteButtons.length; i++) {
deleteButtons[i].addEventListener('click', () => {
productName = deleteButtons[i].parentElement.textContent.toLocaleLowerCase().replace(/ /g,'').trim();
localStorage.setItem('cartNumbers', productNumbers - cartItems[productName].inCart);
localStorage.setItem('totalCost', cartCost - ( cartItems[productName].price * cartItems[productName].inCart));
delete cartItems[productName];
localStorage.setItem('productsInCart', JSON.stringify(cartItems));
displayCart();
onLoadCartNumbers();
})
}
}
function checkout(){
emptyCart();
alert("Your order has been placed successfully.");
}
function emptyCart(){
localStorage.clear();
location.reload();
}
onLoadCartNumbers();
displayCart();
And finally, this is the cart.html file
<body>
{{>header2}}
<div class="container-products">
<div class="product-header">
<div class="cart-h">Your Cart</div>
</div>
<div class="products">
<! -- This section is populated using Javascript -->
</div>
</div>
{{>footer}}
<script src="js/main.js"></script>
<script src="js/index.js"></script>
<script src="https://unpkg.com/ionicons#4.5.10-0/dist/ionicons.js"></script>
</body>
The problem is the event listeners for the click events are being registered to the matching elements before you add the new ones.
One simple solution is to NOT have an event listener for the actual buttons, but instead tie it to document, then just look for the appropriate class on the button.
This answer is very rudimentary, its just to demonstrate the concept. If you notice the buttons are added to the DOM AFTER the event listener, but it still works.
document.addEventListener("click",function(e){
let btn = e.target;
if(btn.className.includes("increase")){
console.log("increase")
}
else if(btn.className.includes("decrease")){
console.log("decrease")
}
});
let dest = document.querySelector("#dest");
dest.innerHTML = '<button class="increase">Increase</button><button class="decrease">Decrease</button>';
<div id="dest"></div>

Changing color of an id with Javascript

I get all movie datas from Firebase and also i get score of the movies. If the score of the movie is higher than 70, then i will change color of the id as "deepskyblue", if it is 50 or higher it will be "orange" and lastly if it is lower than 50 it will be "crimson"(red). When i do this, it only changes my first movie's id's color. But i wanna change all of them. How can i do this?
My Website
Console.log(i)
var movieNo = 0;
let html = '';
var body = document.getElementById('editor');
var body2 = document.getElementById('week');
function AddItemsToTable(name, score, img, id) {
var movies = `<div class="content"><img src="${img}" ><p>${name}</p> <p> <i class="fa fa-star" id="star"></i> <a class="scoretxt">${score}</a> </p> </div>`;
html = movies;
body.innerHTML += html;
body2.innerHTML += html;
}
function AddAllItemsToTable(TheMovies) {
movieNo = 0;
var counter = 0;
TheMovies.forEach(element => {
if (counter === 6) {
return;
}
AddItemsToTable(element.movieName, element.movieScore, element.movieImage, element.movieId);
var i = document.getElementsByClassName("fa fa-star")[element.movieId];
console.log(i);
if (element.movieScore >= 70) {
i.style.color = "deepskyblue"; //good movie
} else if (element.movieScore >= 50) {
i.style.color = "orange"; //not bad
} else {
i.style.color = "crimson"; //bad movie
}
counter++;
});
}
function getAllDataOnce() {
const dbRef = ref(db);
get(child(dbRef, "Movies"))
.then((snapshot) => {
var movies = [];
snapshot.forEach(childSnapshot => {
movies.push(childSnapshot.val())
});
AddAllItemsToTable(movies);
});
}
window.onload = getAllDataOnce;
<div class="body" id="body">
<div class="baslik">Opening This Week</div>
<div class="baslik2">See all</div>
<div id="week">
</div>
<div class="baslik">Editor's Picks</div>
<div class="baslik2">See all</div>
<div id="editor">
</div>
</div>
I suggest to change the logic.
Your mistake is that you use the same id several times, and it should be unique (1 element = 1 unique id).
Try to make it like this:
// AddAllItemsToTable function
if (element.movieScore >= 50 && element.movieScore < 70 ) {
i.classList.add("deepskyblue"); // good movie
} else if (element.movieScore >= 70) {
i.classList.add("orange"); // not bad
} else {
i.classList.add("crimson"); // bad movie
}
After that, add the following rules to your styles file:
.deepskyblue {
color: deepskyblue;
}
.orange {
color: orange;
}
.crimson {
color: crimson;
}
Everything will work as it should and as a bonus it will be easier to manage styles and and you won't have to fix JS code for this.
Make a function
NOTE IDs need to be unique
const scoreColor = score => {
const color = "crimson"
if (score >= 70) return "deepskyblue"; //good movie
if (score >= 50) return "orange"; //not bad
return score;
};
function AddItemsToTable(name, score, img, id) {
const movies = `<div class="content">
<img src="${img}" >
<p>${name}</p>
<p><i class="fa fa-star"></i> <a class="${scoreColor(score)}">${score}</a></p>
</div>`;
body.innerHTML += movies;
body2.innerHTML += movies;
}

How to beat a JavaScript condition riddle?

I am using a foreach loop in php to load data from a mysql table. I'm using the data ID's loaded from the data base and applying it to the button values.
The buttons come in two colors, green and white. The buttons represent likes for liking comments or posts.
The total existing number of likes starts at 6 (div id="total")
white buttons
If button 1 has color of white and you click it, total likes (6) will increase by 1. If you click button 1 again, total likes (7) will decrease by 1.
If button 1, button 2, and button three are clicked, total likes (6) increases by 3 ( 1 for each button). If button 1, button 2 and button 3 are clicked again, the total likes (9) will decrease by 3.
The Puzzle
Green buttons
How do I make it so, When a green button is clicked, the total (6) decrease by 1, and if the button is clicked again, it should increase by 1. Unlike white buttons.
If Green button 3, 5 and 6 are clicked, the total (6) should decease by 3. if the same buttons are clicked again, total (6) increases by 3.
Here is my code
var colorcode = "rgb(116, 204, 49)";
var buttonid = str;
var elem = document.getElementById(buttonid);
var theCSSprop = window.getComputedStyle(elem, null).getPropertyValue("background-color");
var initialtotal = parseInt(document.getElementById("total").innerHTML, 10);
var likes = new Array();
function showUser(str) {
////// 1st condition /////
if (theCSSprop == colorcode) {
if (likes[value] == 0 || !likes[value]) {
likes[value] = 1;
} else {
likes[value] = 0;
}
var sum = 0;
for (i = 0; i < likes.length; i++) {
if (likes[i] == 1) {
sum--
}
}
}
////// 2nd condition /////
else {
if (likes[str] == 0 || !likes[str]) {
likes[str] = 1;
} else {
likes[str] = 0;
}
var sum = 0;
for (i = 0; i < likes.length; i++) {
if (likes[i] == 1) {
sum++
}
}
}
var tot = initialtotal + sum;
document.getElementById("total").innerHTML = tot;
}
<div id="total" style="width:100px;padding:50px 0px; background-color:whitesmoke;text-align:center;">6 </div>
<!---------------------------------------------------------------------------------------------------------------------->
<button id="5" value="5" onclick="showUser(this.value)">LIKE </button>
<button id="346" value="346" onclick="showUser(this.value)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="128" value="128" onclick="showUser(this.value)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="687" value="687" onclick="showUser(this.value)">LIKE </button>
<button id="183" value="183" onclick="showUser(this.value)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="555" value="555" onclick="showUser(this.value)">LIKE </button>
<!---------------------------------------------------------------------------------------------------------------------->
Instead of passing this.value to showUser(), just pass this. That way, the function can get the value and the style directly, without having to call getElementById() (you're not passing the ID). Then you need to set theCSSprop inside the function, so it's the property of the current button.
To make green buttons alternate direction from increment to decrement, you need a global variable that remembers what it did the last time the function was called.
Also, you don't need to write if(likes[str] == 0 || !likes[str]), since 0 is faley. Just write if(!likes[str]).
var colorcode = "rgb(116, 204, 49)";
var likes = new Array();
var greenIncr = -1;
function showUser(elem) {
var initialtotal = parseInt(document.getElementById("total").innerHTML, 10);
////// 1st condition /////
var str = elem.value;
var theCSSprop = window.getComputedStyle(elem, null).getPropertyValue("background-color");
if (theCSSprop == colorcode) {
if (!likes[str]) {
likes[str] = 1;
} else {
likes[str] = 0;
}
var sum = 0;
for (i = 0; i < likes.length; i++) {
if (likes[i] == 1) {
sum += greenIncr;
}
}
greenIncr = -greenIncr; // revese the direction of green button
}
////// 2nd condition /////
else {
if (!likes[str]) {
likes[str] = 1;
} else {
likes[str] = 0;
}
var sum = 0;
for (i = 0; i < likes.length; i++) {
if (likes[i] == 1) {
sum++
}
}
}
var tot = initialtotal + sum;
document.getElementById("total").innerHTML = tot;
}
<div id="total" style="width:100px;padding:50px 0px; background-color:whitesmoke;text-align:center;">6 </div>
<!---------------------------------------------------------------------------------------------------------------------->
<button id="5" value="5" onclick="showUser(this)">LIKE </button>
<button id="346" value="346" onclick="showUser(this)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="128" value="128" onclick="showUser(this)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="687" value="687" onclick="showUser(this)">LIKE </button>
<button id="183" value="183" onclick="showUser(this)" style="background-color:rgb(116, 204, 49);">LIKE </button>
<button id="555" value="555" onclick="showUser(this)">LIKE </button>
<!---------------------------------------------------------------------------------------------------------------------->
First naive implementation can look like this
class Counter {
constructor(initial) {
this.initial = initial
this.white = [false, false, false]
this.green = [false, false, false]
}
changeGreen(index) {
this.green[index] = !this.green[index]
}
changeWhite(index) {
this.white[index] = !this.white[index]
}
get total() {
return this.initial + this.white.reduce((total, current) => total + current, 0) + this.green.reduce((total, current) => total - current, 0)
}
}
let counter = new Counter(6)
const render = counter => {
document.querySelector('#total').innerHTML = counter.total
}
render(counter)
;['#first', '#second', '#third'].map((selector, index) => {
document.querySelector(selector).addEventListener('click', e => {
e.target.classList.toggle('pressed')
counter.changeWhite(index)
render(counter)
})
})
;['#fourth', '#fifth', '#sixth'].map((selector, index) => {
document.querySelector(selector).addEventListener('click', e => {
e.target.classList.toggle('pressed')
counter.changeGreen(index)
render(counter)
})
})
.green {
background: #00aa00
}
.pressed {
border-style: inset
}
<div id="total">0</div>
<p>
<button id="first">First</button>
<button id="second">Second</button>
<button id="third">Third</button>
<button id="fourth" class="green">Fourth</button>
<button id="fifth" class="green">Fifth</button>
<button id="sixth" class="green">Sixth</button>
</p>
But after all I've finished with something like
class Counter {
constructor(initial, strategy) {
this.initial = initial;
this.elements = [];
this.strategy = typeof strategy === 'function' ? strategy : () => {}
}
addElement(content, type, next) {
const element = {
content: content,
type: type,
state: false
};
this.elements.push(element);
return next(element, this.elements.length - 1);
}
toggleElementState(index) {
this.elements[index].state = !this.elements[index].state
}
get total() {
return this.strategy(this.initial, this.elements)
}
}
const initialize = () => {
Counter.WHITE = Symbol('white');
Counter.GREEN = Symbol('green');
const counter = new Counter(6, (initial, buttons) => {
return initial +
buttons.filter(button => button.type === Counter.WHITE).reduce((total, current) => total + Number(current.state), 0) +
buttons.filter(button => button.type === Counter.GREEN).reduce((total, current) => total - Number(current.state), 0)
});
const render = counter => {
document.querySelector('#total').innerHTML = counter.total
};
const createButton = (element, index) => {
const button = document.createElement('button');
button.setAttribute('data-id', index);
button.classList.add(element.type === Counter.GREEN ? 'green' : 'none');
button.textContent = element.content;
document.querySelector('#buttons').appendChild(button)
};
const addButton = (type, ...selectors) => {
selectors.forEach(selector => counter.addElement(selector, type, createButton));
};
render(counter);
addButton(Counter.WHITE, '#first', '#second', '#third');
addButton(Counter.GREEN, '#fourth', '#fifth', '#sixth');
addButton(Counter.WHITE, '#first', '#second', '#third');
document.querySelector('#buttons').addEventListener('click', function(e) {
e.target.classList.toggle('pressed');
counter.toggleElementState(parseInt(e.target.dataset.id));
render(counter)
})
};
document.addEventListener('DOMContentLoaded', initialize);
.green {
background: #00aa00
}
.pressed {
border-style: inset
}
<div id="total">0</div>
<p id="buttons">
</p>

Categories

Resources