how to add input value to counter value? - javascript

I'm trying to have a counter that can respond to input values and add it to displayed count but continue to count by 1. The count starts at 0. I have the counter working with buttons, but not with the added input.
let decreaseBtn = document.getElementById("buttonDecrease");
let increaseBtn = document.getElementById("buttonIncrease");
let counter = document.getElementById("counter");
let inputValue = document.getElementById("quantity").inputValue
let count = 0;
decreaseBtn.addEventListener("click", () => {
count--;
counter.innerHTML = count;
counterStyle();
});
increaseBtn.addEventListener("click", () => {
count++;
counter.innerHTML = count;
counterStyle();
});
function counterStyle() {
if (count < 0) {
counter.classList.add("negative");
} else if (count > 0) {
counter.classList.add("positive");
} else {
counter.classList.remove("negative");
counter.classList.remove("positive");
}
}
function addInput() {
console.log(inputValue)
}
addInput();
<h1 id="counter">0</h1>
<div id="button__wrapper">
<button id="buttonDecrease">-</button>
<input type="text" id="quantity" value="1">
<button id="buttonIncrease">+</button>
</div>

Yuo need to get the value of the input in your event listener functions, not when the script starts. Then use that instead of just incrementing and decrementing.
The property to get the value of an input is .value, not .inputValue.
let decreaseBtn = document.getElementById("buttonDecrease");
let increaseBtn = document.getElementById("buttonIncrease");
let counter = document.getElementById("counter");
let quantity = document.getElementById("quantity");
let count = 0;
decreaseBtn.addEventListener("click", () => {
count -= addInput();
counter.innerHTML = count;
counterStyle();
});
increaseBtn.addEventListener("click", () => {
count += addInput();
counter.innerHTML = count;
counterStyle();
});
function counterStyle() {
if (count < 0) {
counter.classList.add("negative");
counter.classList.remove("positive");
} else if (count > 0) {
counter.classList.add("positive");
counter.classList.remove("negative");
} else {
counter.classList.remove("negative");
counter.classList.remove("positive");
}
}
function addInput() {
return parseInt(quantity.value);
}
.positive {
background-color: green;
}
.negative {
background-color: red;
}
<h1 id="counter">0</h1>
<div id="button__wrapper">
<button id="buttonDecrease">-</button>
<input type="text" id="quantity" value="1">
<button id="buttonIncrease">+</button>
</div>

You have increment and decrement operators when you handle the click event. This is why it is always just adding or subtracting by 1, and not by the value of the input. You should be adding the value of the input element, after using parseInt() to make it into an add-able integer.
Your code that I'm changing:
count--;
What I'm changing it to...
count -= parseInt(document.getElementById('quantity').value, 10);
And I'm doing the same for count++.
In addition, it seems your counterStyles() function isn't removing classes appropriately, and sometimes you'll have a red background with positive integers. I fixed this up by adding the needed removeClass() calls here.
The rest of the code is the same...
let decreaseBtn = document.getElementById("buttonDecrease");
let increaseBtn = document.getElementById("buttonIncrease");
let counter = document.getElementById("counter");
let inputValue = document.getElementById("quantity").inputValue
let count = 0;
decreaseBtn.addEventListener("click", () => {
count -= parseInt(document.getElementById('quantity').value, 10);
counter.innerHTML = count;
counterStyle();
});
increaseBtn.addEventListener("click", () => {
count += parseInt(document.getElementById('quantity').value, 10);
counter.innerHTML = count;
counterStyle();
});
function counterStyle() {
if (count < 0) {
counter.classList.add("negative");
counter.classList.remove("positive");
} else if (count > 0) {
counter.classList.add("positive");
counter.classList.remove("negative");
} else {
counter.classList.remove("negative");
counter.classList.remove("positive");
}
}
function addInput() {
console.log(inputValue)
}
addInput();
.positive {
background-color: green;
}
.negative {
background-color: red;
}
<h1 id="counter">0</h1>
<div id="button__wrapper">
<button id="buttonDecrease">-</button>
<input type="text" id="quantity" value="1">
<button id="buttonIncrease">+</button>
</div>

Related

is it possible to access classes inside if statement?? the output what i am getting is wrong

let count = 0;
let counter = document.querySelector("#number-el");
let btns = document.querySelectorAll(".btn");
let decreaseEl = document.querySelector(".decrease-el");
let increaseEl = document.querySelector(".increase-el");
btns.forEach(function(btn) {
btn.addEventListener("click", function() {
if (decreaseEl) {
count--;
console.log(count);
} else if (increaseEl) {
count++;
} else {
count = 0;
}
if (count < 0) {
counter.style.color = "green";
}
if (count > 0) {
counter.style.color = "red";
}
if (count === 0) {
counter.style.color = "yellow";
}
counter.textContent = count;
});
});
<div class="container">
<div>
<p id="counter-el">COUNTER
<div id="number-el">0</div>
</p>
<button class="btn increase-el">INCREASE</button>
<button class="btn reset-el">RESET</button>
<button class="btn decrease-el">DECREASE</button>
</div>
</div>
It's a program to perform a counter which increases, decreases, and reset the count from 0, but the output that I am getting is only increasing with a negative sign
i access classes inside if statement directly. is it possible to directly access classes without using event objects.
Added values in button and used switch/case
let count = 0;
let counter = document.querySelector("#number-el");
let btns = document.querySelectorAll(".btn");
let decreaseEl = document.querySelector(".decrease-el");
let increaseEl = document.querySelector(".increase-el");
btns.forEach(function(btn) {
btn.addEventListener("click", function(e) {
switch (e.target.value) {
case "INCREASE":
count++;
break;
case "DECREASE":
count--;
break;
case "RESET":
count = 0;
break;
default:
break;
}
if (count < 0) {
counter.style.color = "green";
}
if (count > 0) {
counter.style.color = "red";
}
if (count === 0) {
counter.style.color = "yellow";
}
counter.textContent = count;
});
});
<div class="container">
<div>
<p id="counter-el">COUNTER
<div id="number-el">0</div>
</p>
<button class="btn increase-el" value="INCREASE">INCREASE</button>
<button class="btn reset-el" value="RESET">RESET</button>
<button class="btn decrease-el" value="DECREASE">DECREASE</button>
</div>
</div>
Change
btn.addEventListener("click", function () {
if (decreaseEl) { ... }
into
btn.addEventListener("click", function (ev) {
if (ev.target.closest(".btn") == decreaseEl) { ... }
as otherwise the if will always be fulfilled (true). ev.target.closest(".btn") == decreaseEl will check, whether you have clicked on the decreaseEl DOM element or on any of its children.

How to update created elements?

I have this simple function that will create a paragraph.
function appendElements() {
const input = document.getElementById("myInput");
const createDiv = document.createElement("div");
createDiv.classList.add("myDiv");
const createP = document.createElement("P");
createP.classList.add("myParagraph");
createP.innerHTML = input.value;
createDiv.appendChild(createP);
const div = document.getElementById("examplediv");
div.appendChild(createDiv);
}
And another function that will sum the innerHTML of the divs, and create a div element for the result.
function calculateSum() {
let div = document.getElementsByClassName("myParagraph");
let array = new Array;
for (var i = 0; i <div.length; i++) {
array.push(div[i].innerHTML);
}
let numberedArray = array.map((i) => Number(i));
const sumArray = numberedArray.reduce(function(a, b){
return a + b;
}, 0);
const createElement = document.createElement("div");
createElement.innerHTML = sumArray;
document.getElementById("divForAvg").appendChild(createElement);
}
And the last function that will change the innerHTML of the paragraph element when clicked.
function editELement() {
const input2 = document.getElementById("myInput2")
let items = document.getElementsByClassName("myParagraph");
for(var i = 0; i < items.length; i++){
items[i].onclick = function(){
items[i].innerHTML = input2.value;
}
}
}
So basically when I create some paragraphs and execute the second function, the second function will calculate the sum of the paragraphs and create a div with the sum inside.
What I want is when I remove one of the paragraph elements or edit them, I want the previously created divs to update(recalculate the sum), I have literally no idea on how to do this.
Let's try this using event delegation. I have interpreted what I think you are looking for (note: it's exemplary, but it may give you an idea for your code) and reduced your code a bit for the example. Note the 2 different ways to create new elements (insertAdjacentHTML and Object.assign).
You can play with the code #Stackblitz.com.
document.addEventListener("click", handle);
function handle(evt) {
if (evt.target.id === "create") {
return appendInputValueElement();
}
if (evt.target.classList.contains("remove")) {
return removeThis(evt.target);
}
if (evt.target.id === "clear") {
document.querySelector("#accumulated ul").innerHTML = "";
return true;
}
}
function appendInputValueElement() {
const input = document.querySelector(".myInput");
const div = document.querySelector("#exampleDiv");
exampleDiv.insertAdjacentHTML("beforeEnd", `
<div class="myDiv">
<button class="remove">remove</button>
<span class="myParagraph">${input.value || 0}</span>
</div>
`);
calculateSum();
}
function removeThis(elem) {
elem.closest(".myDiv").remove();
calculateSum();
}
function calculateSum() {
const allParas = [...document.querySelectorAll(".myParagraph")];
const sum = allParas.reduce( (acc, val) => acc + +val.textContent, 0);
document.querySelector("#accumulated ul")
.append(Object.assign(document.createElement("li"), {textContent: sum}));
document.querySelector(".currentSum").dataset.currentSum = sum;
if (sum < 1) {
document.querySelector("#accumulated ul").innerHTML = "";
}
}
.currentSum::after {
content: ' 'attr(data-current-sum);
color: green;
font-weight: bold;
}
.myParagraph {
color: red;
}
.accSums, .currentSum, .myDiv {
margin-top: 0.3rem;
}
<div>
A number please: <input class="myInput" type="number" value="12">
<button id="create">create value</button>
</div>
<div class="currentSum" data-current-sum="0">*Current sum</div>
<p id="exampleDiv"></p>
<div id="accumulated">
<div class="accSums">*Accumulated sums</div>
<ul></ul>
<button id="clear">Clear accumulated</button>
</div>
i've changed calculateSum you can call it when you edited paragraph. If summParagraph doesn't exists then we create it.
function calculateSum() {
let div = document.getElementsByClassName("myParagraph");
let array = new Array;
for (var i = 0; i <div.length; i++) {
array.push(div[i].innerHTML);
}
let numberedArray = array.map((i) => Number(i));
const sumArray = numberedArray.reduce(function(a, b){
return a + b;
}, 0);
if (!document.getElementById("summParagraph")) {
const createElement = document.createElement("div");
createElement.setAttribute("id", "summParagraph");
document.getElementById("divForAvg").appendChild(createElement);
}
document.getElementById("summParagraph").innerHTML = summArray;
}

Add/decrease value on click

I have some code that I've implemented as a counter, however, can this code be slightly modified to allow a button to increase a value by 200 and then decrease down to 0? I understand that ++x will increase, but I'm not sure why +x won't add? Is it something to do with strings?
Javascript:
let x = 200;
$('.counter-button.counter-up').on('click', () => {
$('.counter-input.w-input').val( +x );
});
$('.counter-button.counter-down').on('click', () => {
if (x > 0) {
$('.counter-input.w-input').val( -x );
}
});
$('.counter-input.w-input').change(function () {
const num = Number($(this).val());
// if it's a number
if (num) {
// assign its value to x
x = num;
}
});
Thanks for any help with this!
For the record (honoring your initial question): here's a 'vanilla' solution.
{
document.addEventListener("click", addOrSubtract);
function addOrSubtract(evt) {
const from = evt.target;
if (from.dataset.addvalue) {
const numberInput = document.querySelector("input");
const newValue = +numberInput.value + +from.dataset.addvalue;
numberInput.value = newValue >= +numberInput.min
&& newValue <= +numberInput.max ? newValue : numberInput.value;
}
}
}
<input type="number" min="0" max="4000" value="0" readonly>
<button data-addvalue="200">increment</button> (max 4000)
<button data-addvalue="-200">decrement</button> (min 0)
.val() doesn't increase or decrease, it assigns. Try:
$('.counter-input.w-input').val( $('.counter-input.w-input').val() + x );
When you pass +x or -x it will just set that value as a value of the input. So you could first calculate the new value by adding or subtracting x of the current value based on the clicked button class.
let x = 200;
let input = document.querySelector('.counter-input.w-input')
let buttons = document.querySelectorAll('.counter-button')
buttons.forEach(b => {
b.addEventListener('click', function() {
let value = +input.value;
if (this.classList.contains('counter-up')) {
value += x
} else if (value > 0) {
value -= x
}
input.value = value
})
})
<button class="counter-button counter-up">Up</button>
<button class="counter-button counter-down">Down</button>
<input value="0" type="text" class="counter-input w-input">

how to continually add to a price total in a shopping list

i'm trying to write a program that keeps adding to the current total price displayed as the user keeps inputting/adding more items in the text box area. The code i wrote currently resets the price every time a user inputs/adds an item into the text box. Please how can i solve this problem. I need items and price added to the text box to be added to the current amkunt displayed and not start from the beginning.
function getPrice(itemField) {
return itemField.value || 0;
}
function updateItemfield(itemField) {
var item = getPrice(itemField);
if (getPrice(itemField)) {
itemField.value = item;
} else {
itemField.value = itemField.defaultValue;
}
}
function displayItems(disp, goods) {
hide(disp);
if (goods != 0) {
show(disp);
disp.innerHTML = goods;
}
}
function getQuantity(quantityField) {
return parseInt(quantityField.value, 10) || 0;
}
function updateItemQuantity(itemField, quantityField) {
var quantity = getQuantity(quantityField);
if (quantity < 1) {
quantity = 1;
}
if (getPrice(itemField)) {
quantityField.value = quantity;
} else {
quantityField.value = quantityField.defaultValue;
}
}
function getItemTotal(itemField, quantityField) {
return getPrice(itemField) * getQuantity(quantityField);
}
function hide(el) {
el.className = 'hidden';
}
function show(el) {
el.className = '';
}
function updateTotal(el, amount) {
hide(el);
if (amount > 0) {
show(el);
el.innerHTML = "Your Order Total is $" + amount;
}
}
function forEachFormItem(form, items, func) {
var i,
item,
itemField,
quantityField,
result = 0;
for (i = 0; i < items.length; i += 1) {
item = items[i];
itemField = form.elements[item],
quantityField = form.elements[item + 'quantity'],
result += func(itemField, quantityField);
}
return result;
}
// function addRecord() {
// var inp = document.getElementById('inputtext');
// quotes.push(inp.value);
// inp.value = "";
// }
function calculateTotal() {
var form = this,
items = ['wine'],
total = 0,
priceField = form.priceField;
forEachFormItem(form, items, updateItemQuantity);
total = forEachFormItem(form, items, getItemTotal);
updateTotal(priceField, total);
}
var goods = [];
function addItems() {
var inp = document.getElementById('inputtext');
goods.push(inp.value);
inp.value = "";
}
function newItem() {
document.getElementById("itemDisplay").innerHTML = goods.join(", ");
}
var theForm = document.getElementById('order');
theForm.priceField = document.getElementById('totalPrice');
theForm.onchange = calculateTotal;
.hidden {
display: none;
}
<form id="order" method="post" action="mailto:seyicole#gmail.com">
<fieldset id="selections">
<legend><strong>Your Selections</strong></legend>
<img class="wine" src="wine.png" alt="Select Your Items!!">
<p>
<label>Wine:</label>
<input type="text" name="" id="inputtext" placeholder="item">
<input type="text" name="wine" value="0" size="8">
<input type="text" name="winequantity" value="Quantity" size="8">
<button type="button" id="add" onclick="addItems(), newItem()";>Add </button>
</p>
</fieldset>
<h1>Items</h1>
<div id="itemDisplay">
</div>
<br>
<input type="submit" value="Place order">
</form>
<div id="totalPrice"></div>
The problem is that you are not storing the entered goods anywhere, you are just storing the names.
I recommend that instead of just storing the name, you store an object containing added goods, along with the total amount.
function getPrice(itemField) {
return itemField.value || 0;
}
function updateItemfield(itemField) {
var item = getPrice(itemField);
if (getPrice(itemField)) {
itemField.value = item;
} else {
itemField.value = itemField.defaultValue;
}
}
function displayItems(disp, goods) {
hide(disp);
if (goods != 0) {
show(disp);
disp.innerHTML = goods;
}
}
function getQuantity(quantityField) {
return parseInt(quantityField.value, 10) || 0;
}
function updateItemQuantity(itemField, quantityField) {
var quantity = getQuantity(quantityField);
if (quantity < 1) {
quantity = 1;
}
if (getPrice(itemField)) {
quantityField.value = quantity;
} else {
quantityField.value = quantityField.defaultValue;
}
}
function getItemTotal(itemField, quantityField) {
return getPrice(itemField) * getQuantity(quantityField);
}
function hide(el) {
el.className = 'hidden';
}
function show(el) {
el.className = '';
}
function updateTotal(el, amount) {
hide(el);
if (amount > 0) {
show(el);
el.innerHTML = "Your Order Total is $" + amount;
}
}
function forEachFormItem(form, items, func) {
var i,
item,
itemField,
quantityField,
result = 0;
for (i = 0; i < items.length; i += 1) {
item = items[i];
itemField = form.elements[item],
quantityField = form.elements[item + 'quantity'],
result += func(itemField, quantityField);
}
return result;
}
// function addRecord() {
// var inp = document.getElementById('inputtext');
// quotes.push(inp.value);
// inp.value = "";
// }
function calculateTotal() {
var form = this,
items = ['wine'],
total = 0,
priceField = form.priceField;
// Get total goods and update total
total = goods.reduce((a, c) => a + c.total, 0);
updateTotal(totalPrice, total);
}
var goods = [];
function addItems() {
var inp = document.getElementById('inputtext');
// Calculate total price
const itemField = theForm.elements['wine'];
const quantityField = theForm.elements['winequantity'];
const total = getItemTotal(itemField, quantityField);
// Store name and total price
goods.push({name: inp.value, total});
inp.value = "";
}
function newItem() {
document.getElementById("itemDisplay").innerHTML = goods.map(x => x.name).join(", ");
}
var theForm = document.getElementById('order');
theForm.priceField = document.getElementById('totalPrice');
.hidden {
display: none;
}
<form id="order" method="post" action="mailto:seyicole#gmail.com">
<fieldset id="selections">
<legend><strong>Your Selections</strong></legend>
<img class="wine" src="wine.png" alt="Select Your Items!!">
<p>
<label>Wine:</label>
<input type="text" name="" id="inputtext" placeholder="item">
<input type="text" name="wine" value="0" size="8">
<input type="text" name="winequantity" placeholder="Quantity" size="8">
<button type="button" id="add" onclick="addItems(), newItem(), calculateTotal()" ;>Add </button>
</p>
</fieldset>
<h1>Items</h1>
<div id="itemDisplay">
</div>
<br>
<input type="submit" value="Place order">
</form>
<div id="totalPrice"></div>

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