I wanted to make a food order app, and try to make the quantity buttons like this with my own code: https://css-tricks.com/examples/InputNumberIncrementer/
I struggled with the results. There is an input which will set the quantity once incButtons or decButtons is clicked.
But when I click a button, all the inputs change. How do I fix it, if I want the input to change only on the clicked button, not set to all inputs?
this is my source code :
let incButton = document.querySelectorAll('.inc');
let decButton = document.querySelectorAll('.dec');
// Increment Button
for (let i = 0; i < incButton.length; i++){
incButton[i].addEventListener('click', function() {
// show the decButton when quantity > 1
decButton[i].style.display = 'inline';
// increment the quantity when incButton clicked
for (let i = 0; i < incButton.length; i++){
let inputField = document.querySelectorAll('.quantityNumber');
if(incButton) {
let newVal = parseInt(inputField[i].value) + 1;
inputField[i].value = newVal;
console.log('Quantity +1 added');
}
}
});
};
// Decrement Button
for (let i = 0; i < decButton.length; i++) {
decButton[i].addEventListener('click', function () {
let inputField = document.querySelectorAll('.quantityNumber');
for (let i = 0; i < inputField.length; i++) {
// if decButton is clicked and quantitiy >= 2 decrement it
if (decButton[i] && inputField[i].value >= 2) {
let newVal = parseInt(inputField[i].value) - 1;
inputField[i].value = newVal;
console.log('Quantity -1 reduced');
}
// hide the decButton when quantity is 1
if (inputField[i].value == 1) {
decButton[i].style.display = 'none';
}
}
});
};
<div class="quantity">
<button class="dec">-</button>
<input type="text" class="quantityNumber" value="1">
<button class="inc">+</button>
</div>
<br>
<div class="quantity">
<button class="dec">-</button>
<input type="text" class="quantityNumber" value="1">
<button class="inc">+</button>
</div>
Please help me to solve this, and thank you before for the questions :)
Related
<div id="agg-filter-buttons">
<button class="btn filter-btn" onclick="filterSelection(event)"><span data-
value="freespins">Free Spins <div class="num-brands"></div> </span></button>
<button class="btn filter-btn" onclick="filterSelection(event)"> <span data-value="bigbonus">Big Bonus <div class="num-brands"></div> </span></button> </div>
enter code here
</div>
<div class="brand-row the-table-row all row-1 filterDiv bigbonus newPlay show">
Row 1
</div>
<div class="brand-row the-table-row all row-2 filterDiv freespins newPlay show">
Row 2
</div>
filterSelection();
function filterSelection(e) {
var x, i, c;
x = document.getElementsByClassName("filterDiv");
var allBtns = document.getElementsByClassName("filter-btn")
for(i = 0; i<allBtns.length; i++){
let rowsAffected = allBtns[i].querySelector('.num-brands');
rowsAffected.innerText = '';
}
c = "all";
if(e && e.target.dataset){
c = e.target.dataset.value ? e.target.dataset.value : "all";
}
const numBrands = [];
for (i = 0; i < x.length; i++) {
x[i].classList.remove('show');
void x[i].offsetWidth;
if (x[i].classList.contains(c)) {
x[i].classList.add('show');
numBrands.push(i);
}
}
if(e && e.target){
e.srcElement.children[0].innerText = ` (${numBrands.length})`;
}
}
// Add active class to the current control button (highlight it)
var btnContainer = document.getElementById("agg-filter-buttons");
var btns = btnContainer.getElementsByClassName("filter-btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function($this) {
var current = document.querySelectorAll(".active-btn");
current[0].className = current[0].className.replace(" active-btn", "");
this.className += " active-btn";
});
}
var filter = document.getElementById('agg-filter-buttons');
filter.addEventListener('click', function(){
document.getElementsByClassName('section--btable')[0].classList.add('flash');
});
filterSelection();
function filterSelection(e) {
var x, i, c;
x = document.getElementsByClassName("filterDiv");
var allBtns = document.getElementsByClassName("filter-btn")
for (i = 0; i < allBtns.length; i++) {
let rowsAffected = allBtns[i].querySelector('.num-brands');
rowsAffected.innerText = '';
}
c = "all";
if (e && e.target.dataset) {
c = e.target.dataset.value ? e.target.dataset.value : "all";
}
const numBrands = [];
for (i = 0; i < x.length; i++) {
x[i].classList.remove('show');
void x[i].offsetWidth;
if (x[i].classList.contains(c)) {
x[i].classList.add('show');
numBrands.push(i);
}
}
if (e && e.target) {
e.srcElement.children[0].innerText = ` (${numBrands.length})`;
}
}
// Add active class to the current control button (highlight it)
var btnContainer = document.getElementById("agg-filter-buttons");
var btns = btnContainer.getElementsByClassName("filter-btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function($this) {
var current = document.querySelectorAll(".active-btn");
current[0].className = current[0].className.replace(" active-btn", "");
this.className += " active-btn";
});
}
var filter = document.getElementById('agg-filter-buttons');
filter.addEventListener('click', function() {
document.getElementsByClassName('section--btable')[0].classList.add('flash');
});
<div id="agg-filter-buttons">
<button class="btn filter-btn" onclick="filterSelection(event)"><span data-
value="freespins">Free Spins <div class="num-brands"></div> </span></button>
<button class="btn filter-btn" onclick="filterSelection(event)"> <span data-value="bigbonus">Big Bonus <div class="num-brands"></div> </span></button> </div>
enter code here
</div>
>
<div class="brand-row the-table-row all row-1 filterDiv bigbonus newPlay show">
Row 1
</div>
<div class="brand-row the-table-row all row-2 filterDiv freespins newPlay show">
Row 2
</div>
So I have a table with rows. These are filtered with the filter buttons. When you click a filter button it shows only the rows with the same name in its class. This works and populates the button with how many rows are affected.
However this breaks occasionally and I have no idea why.
the Variable rowsAffected works until it becomes null for some unknown reason.
My guess is that the dom eventually doesnt load fast enough for the querySelector to be able to read it. But im not sure.. Any advice very welcome!
I have also added a fiddle
https://jsfiddle.net/8z56sxby/
Since you only care about the first .active-btn (because there is at most one), you can just use querySelector.
Make sure there is a current before you do anything with its classes.
Use element.classList.add and element.classList.remove to add or remove classes.
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var current = document.querySelector(".active-btn");
if (current) current.classList.remove("active-btn");
this.classList.add("active-btn");
});
}
Thankyou
The answer to this question was that clicks on my button were sometimes clicking child elements which were not setup to handle the click.
A silly mistake - that someone may find useful in the future.
I'll try to explain : I have a lot of divs that I am using as buttons (they're switching to red when you click on it).
It's a ranking system (for a videogame). Each rank has three step (1-2-3).
The goal of this is that you can select your rank first, then select the desire rank.
After choosing this, the price is displayed. Im trying to do this function.
For example, you select the lowest rank possible, then your landing (1-2-3).
Then, you choose what is the rank that you want, so in total, there is 4 divs clicked.
Finally, the goal of it all is to show the price.
But im having troubles. If you guys have some ideas.
I know that this is not the good way to do it. The code below is an example (Silver 1 to Silver 2).
I'm sure that I can condense this but I don't know how (Because there is a lot of ranks and doing 50 functions is not a good idea I think).
I hope to have been clear and precise, thanks for your help.
//First part
var fer1 = 0;
var bronze1 = 0;
var argent1 = 0;
var or1 = 0;
var platine1 = 0;
var diamant1 = 0;
var immortel1 = 0;
var un1 = 0;
var deux1 = 0;
var trois1 = 0;
//Second part
var fer2 = 0;
var bronze2 = 0;
var argent2 = 0;
var or2 = 0;
var platine2 = 0;
var diamant2 = 0;
var immortel2 = 0;
var un2 = 0;
var deux2 = 0;
var trois2 = 0;
function P1() {
fer1 = 1;
bronze1 = 0;
argent1 = 0;
or1 = 0;
platine1 = 0;
diamant1 = 0;
immortel1 = 0;
if ((fer1 == 1 && fer2 == 1 && un1 == 1 && deux2 == 1)) {
document.getElementById('total').innerHTML = "100€"
} else {
document.getElementById('total').innerHTML = "0€"
}
}
function P8() {
un1 = 1;
deux1 = 0;
trois1 = 0;
if ((fer1 == 1 && fer2 == 1 && un1 == 1 && deux2 == 1)) {
document.getElementById('total').innerHTML = "100€"
} else {
document.getElementById('total').innerHTML = "0€"
}
}
function P11() {
fer2 = 1;
bronze2 = 0;
argent2 = 0;
or2 = 0;
platine2 = 0;
diamant2 = 0;
immortel2 = 0;
if ((fer1 == 1 && fer2 == 1 && un1 == 1 && deux2 == 1)) {
document.getElementById('total').innerHTML = "100€"
} else {
document.getElementById('total').innerHTML = "0€"
}
}
function P99() {
un2 = 0;
deux2 = 1;
trois2 = 0;
if ((fer1 == 1 && fer2 == 1 && un1 == 1 && deux2 == 1)) {
document.getElementById('total').innerHTML = "100€"
} else {
document.getElementById('total').innerHTML = "0€"
}
}
HTML :
<div class="selection2">
<h1 class="unselectable policeOA policeRS" style="background-color:black; color:white;"> VOTRE RANG SOUHAITÉ</h1>
<div class="SousSelection1">
<div class="contenu-grille">
<div class="foc">
<div class="PetitCarre customClass" id="pc11">
<img class="rankss unselectable" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\Rank\Silver.png"/>
<img id="s1" class="unselectable slash1" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\All\Slashwhite.png"/>
</div>
</div>
<div class="foc">
<div class="PetitCarre" id="pc22">
<img class="rankss unselectable" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\Rank\Bronze.png"/>
<img id="s2" class="unselectable slash2" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\All\Slashwhite.png"/>
</div>
</div>
<div class="foc">
<div class="PetitCarre" id="pc33">
<img class="rankss unselectable" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\Rank\Argent.png"/>
<img id="s3" class="unselectable slash3" src="http://localhost:8080/fullvaloAZ\FullValoCreated\HTML\esports\build\assets\images\All\Slashwhite.png"/>
</div>
I think you should give the divs the same class name the select them using querySelectorAll then create forEach loop on them add click event listener for them inside the event check for the current rank and div rank then return the required price also insted of using fer1 fer2 use [fer1,fer2] it would be much better. if you could provide the html maybe I could help more
UPDATE
you can modify this as it fit your project
// ranks variable will hold all the ranks
// currentRank will hold the user current rank if user have current rank
const ranks = document.querySelectorAll(".foc");
const currentRank = document.getElementById("");
const total = document.getElementById("total");
let upgradePrice = 0;
// this will loop over every rank div you have
ranks.forEach(rank=>{
// then we will add event listener for mouse clicks
rank.addEventListener("click",event=>{
// here you will write the upgrade logic like checking the clicked div id
// so you can know which rank is this and if you need to do any
// validation you can do it here then after you finish you can
// add the upgrade cost to upgradePrice variable so you show it to user
// and be able to use it in another part in your code if needed
// also if you want to get id or class of any element in the rank div
// or the parent element of the div you can use `event`
// you can search for the propertys you can use with `event.target` in google
// you can get the id of the div or the id of any element inside it use event argument
// const rankId = event.target.id <- this the div id
upgradePrice+=100
// after you finish you can change the div style to using `event.target.style`
// event.target.style.background = "red"; <- to mark the div as selected
total.innerHTML = `${upgradePrice}€`
})
})
Having a mare with this one...
I have a function, which displays pagination ( 1, 2, 3 etc) buttons, for each page of my todo app results.
Specifically for example, if you click on button 2, you'll see page 2 of the results. Here's the full function and the buttons are being inserted via template literals:
// CREATE BUTTONS FOR EACH PAGE THAT EXISTS
function displayNumberedButtons(bookMarksArray) {
for (let x = 0; x < bookMarksArray.length; x++)
listArray.push(x);
numberOfPages = Math.ceil(listArray.length / numberPerPage);
let individualPagesArray = [];
for (var i = 1; i <= numberOfPages; i++) {
individualPagesArray.push(i);
}
// BUTTONS ARE ADDED HERE
for (var i = 0; i < individualPagesArray.length; i++) {
document.getElementById("numbers").innerHTML += `<button onclick=showCurrentPage(${i+1})>` + individualPagesArray[i] + `</button>`;
}
}
However, my onclick function, does not seem to register in my JavaScript:
// PAGINGATION CTAS
window.showCurrentPage = (i) => {
currentPage = i;
paginationCountLogic(bookMarksArray);
}
If I click on any button, I get the following error. And I have no idea why, as I can see the buttons in my DOM.
index.html:1 Uncaught ReferenceError: showCurrentPage is not defined
at HTMLButtonElement.onclick (index.html:1)
This only happens when I compiled my JS files in advanced mode, using google closure compiler. Otherwise, this works fine if the files are not compiled.
Not sure how to resolve this.
Here is the full order the code appears as in my script:
function Pagination() {
let listArray = new Array(); //store the collection of data to be sorted.
let pageList = new Array(); //keep track of the items to display on the current page only
const numberPerPage = 3;
let currentPage = 1; //keep track of where we are in the pagination
let numberOfPages = 1; // calculates the total number of pages
const list = document.querySelector('.url-list');
let nextButton = document.getElementById("next");
const previousButton = document.getElementById("previous");
let bookMarksArray = window.localStorage.getItem('bookMarksArray') ? JSON.parse(window.localStorage.getItem('bookMarksArray')) : [];
// CREATE BUTTONS FOR EACH PAGE THAT EXISTS
function displayNumberedButtons(bookMarksArray) {
for (let x = 0; x < bookMarksArray.length; x++)
listArray.push(x);
numberOfPages = Math.ceil(listArray.length / numberPerPage);
let individualPagesArray = [];
for (var i = 1; i <= numberOfPages; i++) {
individualPagesArray.push(i);
}
for (var i = 0; i < individualPagesArray.length; i++) {
document.getElementById("numbers").innerHTML += `<button id="${i+1}" onclick=showCurrentPage(${i+1})>` + individualPagesArray[i] + `</button>`;
}
}
// CALCULATE WHEN PAGINATION SHOULD BEGIN AND STOP
function paginationCountLogic(bookMarksArray) {
let begin = ((currentPage - 1) * numberPerPage);
let end = begin + numberPerPage;
pageList = bookMarksArray.slice(begin, end);
nextButton.disabled = currentPage === numberOfPages ? true : false;
previousButton.disabled = currentPage === 1 ? true : false;
displayBookmarks(pageList);
}
// DISPLAY BOOKMARKS
function displayBookmarks(pageList) {
list.innerHTML = "";
for (let r = 0; r < pageList.length; r++) {
list.innerHTML +=
`<div>
<form class="text animated slideInDown bookmarksForm" id=${pageList[r].name}>
<input class="nameItem" type="text" name="name" value=${pageList[r].name} id="name" placeholder="Name">
<input class="urlItem" type="url" name="url" value=${pageList[r].url} id="url" placeholder="https://example.com">
<button type="button" class="js-edit-url" id="edit">edit</button>
<button type="button" class="js-delete-url" id="delete">delete</button>
</form>
</div>`;
}
}
// PAGINGATION CTAS
window.showCurrentPage = (i) => {
currentPage = i;
paginationCountLogic(bookMarksArray);
}
window.nextPage = () => {
currentPage += 1;
paginationCountLogic(bookMarksArray);
}
window.previousPage = () => {
currentPage -= 1;
paginationCountLogic(bookMarksArray);
}
return {
displayNumberedButtons,
displayBookmarks,
paginationCountLogic
};
}
The cause is probably that the compiler doesn't see the function being called. Part of the advanced compilation is removing unused code and renaming the methods/variables.
Within your js or html it is never called because the function call is only defined in a string value here :
for (var i = 0; i < individualPagesArray.length; i++) {
document.getElementById("numbers").innerHTML += `<button onclick=showCurrentPage(${i+1})>` + individualPagesArray[i] + `</button>`;
}
you can solve this pretty simply by rewriting this:
window.showCurrentPage = (i) => {
to this:
window['showCurrentPage'] = (i) => {
See : https://developers.google.com/closure/compiler/docs/api-tutorial3#removal
I am attempting to create an online solver for the maximum subarray problem.
https://en.wikipedia.org/wiki/Maximum_subarray_problem
I planned on taking user-input numbers from a textbox and converting them into an int array in JS, however my JS does not seem to be running at all.
Here is my HTML
<!DOCTYPE html>
<html>
<head>
<title> findMaxSum </title>
<script src="findMaxSum.js" type="text/javascript"></script>
</head>
<body>
<h1> findMaxSum </h1>
<form id="formarray" action="">
<p> Enter numbers with spaces, i.e. "1 2 3 4 5": </p>
<input type="text" id="array"> <br>
<button id="sum">findMaxSum!</button>
<br>
</form>
<p id="answer">The answer is: </p>
</body>
</html>
and my JS. note: the map(function(item)) part of the code is intended to break apart the string from the form into an int array.
"use strict";
function findMaxSum() {
var array = document.getElementById("array").split(" ").map(function(item) {
return parseInt(item, 10);
});
var sumButton = document.getElementById("sum");
sumButton.onclick = findMaxSum;
var loopSum = 0;
var currentMax = 0;
for (var i = 0; i < array.length; i++) {
loopSum += array[i];
if (currentMax < loopSum) {
currentMax = loopSum;
} else if (loopSum < 0) {
loopSum = 0;
}
}
document.getElementById("answer").innerHTML = "The answer is: " + currentMax;
}
window.onload = findMaxSum;
Currently, when I type in numbers into the textbox and submit, the numbers disappear and nothing happens. Any help is greatly appreciated.
Your array variable is object. You have to split the value of <input type="text" id="array"> not the object element.
var array = document.getElementById("array");
array = array.value.split(" ").map(function (item) {
return parseInt(item, 10);
});
Or simpler:
var array = document.getElementById("array").value.split(" ").map(function (item) {
return parseInt(item, 10);
});
Change your code -
function findMaxSum() {
var array = document.getElementById("array").value.split(" ").map(function(item) {
return parseInt(item, 10);
});
var sumButton = document.getElementById("sum");
sumButton.onclick = findMaxSum;
var loopSum = 0;
var currentMax = 0;
for (var i = 0; i < array.length; i++) {
loopSum += array[i];
if (currentMax < loopSum) {
currentMax = loopSum;
} else if (loopSum < 0) {
loopSum = 0;
}
}
document.getElementById("answer").innerHTML = "The answer is: " + currentMax;
}
window.onload = findMaxSum;
Problem is you are using button inside form, which is by default of type submit type, that is the reason why the page goes blank, it gets submitted. So either you don't use form tag or make the button as button type.
<button id="sum" type='button'>findMaxSum!</button> <!-- type attribute added -->
Below is the sample updated code, hope it helps you.
"use strict";
function findMaxSum() {
var array = document.getElementById("array").value.split(/\s/);
var max = Math.max.apply(Math, array);
document.getElementById("answer").innerHTML = "The answer is: " + max;
}
window.onload = function() {
document.getElementById("sum").onclick = findMaxSum;
};
<h1> findMaxSum </h1>
<form id="formarray" action="">
<p>Enter numbers with spaces, i.e. "1 2 3 4 5":</p>
<input type="text" id="array">
<br>
<button id="sum" type='button'>findMaxSum!</button>
<br>
</form>
<p id="answer">The answer is:</p>
To achieve the solution of the problem, you need to make following changes.
Update the event binding place
window.onload = function() {
var sumButton = document.getElementById("sum");
sumButton.onclick = findMaxSum;
};
function findMaxSum() {
// remove the update binding code from here
// logic should come here
}
Resolve a JS error
document.getElementById("array").value.split(" ")
Update the html to avoid page refresh (add type)
<button id="sum" type='button'>findMaxSum!</button>
Update the logic to address the problem
var currentMax = 0;
for (var i = 0; i < array.length; i++) {
var counter = i+1;
while (counter < array.length) {
var loopSum = array[i];
for (var j = (i+1); j <= counter; j++) {
loopSum += array[j];
if(loopSum > currentMax) {
currentMax = loopSum;
}
}
counter++;
}
}
Here is a plunker - http://plnkr.co/edit/AoPANUgKY5gbYYWUT1KJ?p=preview
Please see the fiddle link at the bottom. I have two questions:
How to add HTML text to these radio buttons. I have to give them $ and % value (for the user).
Find the values of every radio button selected. For example, the user added 10 rows (each having 2 radio buttons). I have iterated a loop to find the input type and see if the button is checked and then find its value.
NOT WORKING, guide me what wrong am I doing.
FIDDLE
var i=0;
window.myAdd = function(){
var x = i;
var butts = document.createElement("INPUT");
butts.setAttribute("type", "radio");
butts.setAttribute("name", "currency"+x);
butts.setAttribute("value", "%");
butts.setAttribute("id", "radio"+i);
//var node = document.createTextNode("%");
//butts.appendChild(node);
i=i+1;
//console.log(butts);
var butts_1 = document.createElement("INPUT");
butts_1.setAttribute("type", "radio");
butts_1.setAttribute("name", "currency"+x);
butts_1.setAttribute("value", "$");
butts_1.setAttribute("id", "radio"+i);
i=i+1;
//console.log(butts_1);
var row = document.createElement("TR");
//document.getElementById('tab').appendChild(butts);
//document.getElementById('tab').appendChild(butts_1);
row.appendChild(butts);
row.appendChild(butts_1);
document.getElementById('tab').appendChild(row);
x=x+1;
}
window.myfunction = function(table){
//var x = String(document.getElementById('radioP').value);
//alert(x);
for(var i=0;i<table.elements.length;i++){
if(table.elements[i].type =='radio'){
if(table.elements[i].checked == true){
alert(table.elements[i].value);
}
}
}
}
I have corrected your script to work:
var i = 0;
window.myAdd = function() {
var x = i;
var butts = document.createElement("INPUT");
butts.setAttribute("type", "radio");
butts.setAttribute("name", "currency" + x);
butts.setAttribute("value", "%");
butts.setAttribute("id", "radio" + i);
//var node = document.createTextNode("%");
//butts.appendChild(node);
i = i + 1;
//console.log(butts);
var butts_1 = document.createElement("INPUT");
butts_1.setAttribute("type", "radio");
butts_1.setAttribute("name", "currency" + x);
butts_1.setAttribute("value", "$");
butts_1.setAttribute("id", "radio" + i);
i = i + 1;
//console.log(butts_1);
var row = document.createElement("TR");
//document.getElementById('tab').appendChild(butts);
//document.getElementById('tab').appendChild(butts_1);
row.appendChild(butts);
row.appendChild(butts_1);
document.getElementById('mytable').appendChild(row);
x = x + 1;
}
window.myfunction = function(table) {
//var x = String(document.getElementById('radioP').value);
//alert(x);
//debugger;
for (var i = 0; i < table.rows.length; i++) {
var row = table.rows[i];
for (var j = 0; j < row.childNodes.length; j++) {
if (row.childNodes[j].type == 'radio') {
if (row.childNodes[j].checked == true) {
alert(row.childNodes[j].value);
}
}
}
}
}
<button onclick='myAdd()'>Add Radio Buttons</button>
<table id="mytable" name="mytable"></table>
<button onclick='myfunction(document.getElementById("mytable"))'>GET VALUE</button>
1) You have to use <label> element, e.g.:
<input id="radio_1" type="radio" value="1" />
<label for="radio_1">$</label>
<input id="radio_2" type="radio" value="2" />
<label for="radio_2">%</label>
2) You have to iterate through them. Considering all of the radios are within some div with class "container", you'll need something like this:
document.getElementById('get_values').addEventListener('click', function() {
var radios = document.querySelectorAll('.container input[type="radio"]');
values = {};
for(i=0; i<radios.length; i++) {
var radio = radios[i];
var name = radio.getAttribute('name');
if(radio.checked) {
values[name] = radio.value;
} else {
values[name] = values[name] || null;
}
}
alert(JSON.stringify(values));
});
See this fiddle: http://jsfiddle.net/andunai/gx6quyo0/