I have a problem with the function below. It's taking the data from JSON and it's creating a menu item. The problem is when there are more than 2 menu items, and I try to increase the quantity of the first item then the value of the second item is increasing.
function ShowTheMenu(theCategoryId) {
var parentEl = document.getElementById("itemlist");
ClearMenu();
for (let i = 0; i < data.length; i++) {
if (data[i].KategorijaBroj == theCategoryId) {
// MAIN PARENT
var itemBox = document.createElement("div");
itemBox.classList.add("itembox");
var itemImage = document.createElement("img");
itemImage.classList.add("itemimage");
itemImage.src = "/menuitemsimages/" + data[i].Image;
var itemContent = document.createElement("div");
itemContent.classList.add("itemcontent");
var itemTitle = document.createElement("h3");
itemTitle.classList.add("itemtitle");
itemTitle.innerHTML = data[i].Title;
var itemPrice = document.createElement("p");
itemPrice.classList.add("itemprice");
itemPrice.innerHTML = "$" + data[i].Price;
var itemQnt = document.createElement("p");
itemQnt.classList.add("quantity");
itemQnt.innerHTML = "Quantity";
var buttonsBox = document.createElement("div");
buttonsBox.classList.add("divcontrolbtns");
var itemQuantity = 0;
var quantityValue = document.createElement("div");
quantityValue.innerHTML = itemQuantity;
var increaseBtn = document.createElement("div");
increaseBtn.classList.add("controlbtns");
increaseBtn.innerHTML = "+";
increaseBtn.addEventListener("click", function () {
if(itemQuantity < 10) {
itemQuantity++;
}
quantityValue.innerHTML = itemQuantity;
})
var decreaseBtn = document.createElement("div");
decreaseBtn.classList.add("controlbtns");
decreaseBtn.innerHTML = "-";
decreaseBtn.addEventListener("click", function () {
if(itemQuantity > 0) {
itemQuantity--;
}
quantityValue.innerHTML = itemQuantity;
})
var itemAddToCart = document.createElement("button");
itemAddToCart.classList.add("btn-add-to-cart");
itemAddToCart.textContent = "Add to cart";
var itemDesc = document.createElement("p");
itemDesc.classList.add("itemdesc");
itemDesc.innerHTML = data[i].Description;
itemBox.appendChild(itemImage);
itemContent.appendChild(itemTitle);
itemContent.appendChild(itemDesc);
itemContent.appendChild(itemPrice);
itemContent.appendChild(itemAddToCart);
itemContent.appendChild(itemQnt);
buttonsBox.appendChild(increaseBtn);
buttonsBox.appendChild(quantityValue);
buttonsBox.appendChild(decreaseBtn);
itemContent.appendChild(buttonsBox);
itemBox.appendChild(itemContent);
parentEl.appendChild(itemBox);
}
}
}
IMAGE
What should I do in order for the chosen menu item value to be changed?
Try to do something like this bellow. I try to use same HTML structure that you use but to be honest, I suggest that you change a little bit ;)
<!DOCTYPE html>
<html>
<head>
<script>
// Qt
var quantity = new Array();
function ShowTheMenu(theCategoryId) {
// Clear menu
// ClearMenu();
// bt+
increaseBtn = (i) => {
// Item target
let item = document.getElementById('item_' + i);
// Qt target
let qtSpan = item.getElementsByClassName('qt');
// Qt
let qt = parseInt(qtSpan[0].innerHTML);
// Fix some errors
if (qt === undefined || !qt) qt = 0;
// Increase
if (qt < 10) qt++;
// Update
qtSpan[0].innerHTML = qt;
};
// bt-
decreaseBtn = (i) => {
// Item target
let item = document.getElementById('item_' + i);
// Qt target
let qtSpan = item.getElementsByClassName('qt');
// Qt
let qt = parseInt(qtSpan[0].innerHTML);
// Fix some errors
if (qt === undefined || !qt) qt = 0;
// Decrease
if (qt > 0) qt--;
// Update
qtSpan[0].innerHTML = qt;
};
//
var data = new Array();
data[0] = {
Image:
'https://s2.glbimg.com/WcYUQNaattnUf7d8U8MUBfk7loU=/620x430/e.glbimg.com/og/ed/f/original/2015/10/30/pizza.jpg',
KategorijaBroj: 1,
Title: 'Delicious Pizza',
Price: 10,
Description: 'Description test',
};
for (let i = 0; i < data.length; i++) {
if (data[i].KategorijaBroj == theCategoryId) {
// Img
let img = data[i].Image; // '/menuitemsimages/' + data[i].Image;
// Title
let title = data[i].Title;
// Price
let price = '$' + data[i].Price;
// Description
let desc = data[i].Description;
// Qtd
let qt = 2;
// Matriz
let newItem = `<div id="item_${i}" class="itembox">
<div class="itemcontent">
<img src="${img}" border=0 width=100/>
<h3 class="itemtitle">${title}</h3>
<p class="itemprice">${price}</p>
<div class="quantity">
<span>Quantity : </span>
<span class="qt">${qt}</span>
</div>
<div class="controlbtns">
<button class="addbtn" onClick="increaseBtn(${i})">+</button>
<button class="removebtn" onClick="decreaseBtn(${i})">-</button>
</div>
<button class="btn-add-to-cart">Add to cart</button>
<p class="description">${desc}</p>
</div>
</div>`;
// Get the menulist itens
let parentEl = document.getElementById('itemlist');
// Add item
parentEl.insertAdjacentHTML('beforeend', newItem);
}
}
}
</script>
</head>
<body>
<div id="itemlist"></div>
<script>
ShowTheMenu(1);
</script>
</body>
</html>
It's because both items are sharing the same variable, in this case, itemQuantity.
Option 1
If they all should have their own counter I would recommend using an object for tracking this.
const itemQuantity = {
'item1': 2,
'item2': 5
}
if you add some unique class or id to the element you can use this in your onclick event to use as a key. (Where I used 'item1' and 'item2')
Option 2
If you create a function that does everything that's inside your for loop and then just call that function it should also work. This works because every function then creates its own scoped variable of itemQuanity.
Go with whatever options feel best for now. How to manage data in your frontend has a lot of different ways and opinions. You'll quickly discover what works best in what scenario.
What Olavo Mello is mentioning in his answer could still make your code better. using string literals for small HTML snippets is often more readable than using document.createElement(). I would recommend fixing your counter issue first and then look if you could improve your code with Olavo Mello's answer in mind. Good luck :)
Here what I have so I have a long list of check-boxes and I want to display them in text if they are check I was thinking of using the code below, but the problem I'm having is if they check and uncheck a check-box it shows up multiple times any suggestion on how to fix this?
.innerHTML += id;
If you need some more details here's a code dump of the relevant code:
Javascript
function findTotal() {
var items = new Array();
var itemCount = document.getElementsByClassName("items");
var total = 0;
var id = '';
for (var i = 0; i < itemCount.length; i++) {
id = "c" + (i + 1);
if (document.getElementById(id).checked) {
total = total + parseInt(document.getElementById(id).value);
document.getElementById(id).parentNode.classList.add("active");
document.getElementById(id).parentNode.classList.remove("hover");
document.getElementById('display').innerHTML += id;
} else {
document.getElementById(id).parentNode.classList.remove("active");
document.getElementById(id).parentNode.classList.add("hover");
}
}
console.log(total);
document.getElementById('displayTotal').value = total;
}
HTML
<label class="hover topping" for="c4">
<input class="items" onclick="findTotal()" type="checkbox" name="topping" value="1.00" id="c4">BABYBEL</label>
Note: many more label classes
Previous answer should do it. Here your code (see comment "clear container"
Additionally I have simplified your code a bit. Readability greatly increased.
Maybe you should switch to jQuery in general, much simpler for your example.
var displayElement = document.getElementById('display'),
displayTotalElement = document.getElementById('displayTotal');
function findTotal() {
var items = [],
itemCount = document.getElementsByClassName("items"),
total = 0,
id = '';
// clear container
displayElement.innerHTML = "";
for (var i = 0; i < itemCount.length; i++) {
id = "c" + (i + 1);
var element = document.getElementById(id),
elementsParent = element.parentNode;
if (element.checked) {
total = total + parseInt(element.value, 10);
elementsParent.classList.add("active");
elementsParent.classList.remove("hover");
displayElement.innerHTML += id;
} else {
elementsParent.classList.remove("active");
elementsParent.classList.add("hover");
}
}
console.log(total);
displayTotalElement.value = total;
}
Reset the text before the loop:
document.getElementById('display').innerHTML = '';
At the moment you're just always adding to whatever's already thereā¦
No this isn't a duplicate because all of the answers are different in other posts.
Does anyone know how to get replace something specific in a string? for example I'm trying to get rid of ALL commas that area together. Keep single commas but get rid of two only
For example:
w,h,o,,w,h,a,t,w,h,e,n,w,h,e,r,e,,t,h,e,n,,c,a,n,,b,u,t,,
I want to get rid of all instances where the double commas appear. Something kind of like:
var example = text.replace(/,,/g,' '); /*Space where ' ' is*/
If you understand what I mean. The next step is:
var text.replace(/,/g,'');
Thank you!
Code:
<html>
<head>
<script>
function decrypt() {
var input = document.getElementById("input").value;
var x = input.split(",");
var txtDisp="";
for(var i = 0; i < x.length; i++) {
if(x[i].type = "text") {
crack = 94-(x[i]-32)+32;
toTxt = String.fromCharCode(this, crack);
txtDisp = txtDisp+","+toTxt;
prep = txtDisp.replace(/,,/g,"");
}
document.getElementById("prompt").innerHTML=prep;
}
}
</script>
</head>
<body>
<textarea rows='4' cols='100' style='resize:none;' id='input'></textarea>
<br>
<input type='button' value='execute' onclick='decrypt()' />
<p id='prompt'>
</p>
</body>
</html>
P.s. this code is already posted somewhere else where I asked a question.
Why don't you do:
var text = "61,59,44,47,43,43, ,39,54,37, ,37,47,41,44, ,59,61,48, ,53,48,42,47, ,42,54,57,53,44, ,47,56,42,57,48, ,47,56,56, ,43,61,53,58, ,47,41,44, ,42,39,61,43, ,43,53,48,59,57, ,42,54,57,44,57, ,61,48,58, ,39,47,41,50,58";
example = text.split(",,").join("").split(", ,").join("");
the result is:
"w,h,ow,h,a,t,w,h,e,n,w,h,e,r,et,h,e,nc,a,nb,u,t"
I myself also tried to do it like:
example = text.replace(/,,/g,'').replace(/, ,/g,'');
the result was:
"w,h,ow,h,a,t,w,h,e,n,w,h,e,r,et,h,e,nc,a,nb,u,t"
I changed your code like this:
function decrypt() {
var val = document.getElementById("input").value;
var x = val.split(",");
var txtDisp = "";
for (var i = 0; i < x.length; i++) {
if (!isNaN(parseInt(x[i]))) {
var num = parseInt(x[i]);
crack = 94 - (num - 32) + 32;
toTxt = String.fromCharCode(this, crack);
txtDisp = txtDisp + "," + toTxt;
prep = txtDisp.replace(/,,/g, "").replace(/, ,/g, "");
}
document.getElementById("prompt").innerHTML = prep;
}
}
and it works. check this DEMO out.
Try this:
function decrypt() {
var input = document.getElementById("input").value;
var x = input.split(",");
var txtDisp = "";
for (var i = 0; i < x.length; i++) {
if (x[i] !== ' ') {
crack = 94 - (x[i] - 32) + 32;
toTxt = String.fromCharCode(this, crack);
txtDisp += "," + toTxt;
} else {
txtDisp += " ";
}
}
document.getElementById("prompt").innerHTML = txtDisp.replace(/,/g, "");
}
for(var i=0; i<myJSONObject.model.length; i++){
var create_div = document.createElement('div');
create_div.id = 'model_id'+i;
create_div.innerHTML = myJSONObject.model[i].model_name;
var assign_innerHTML = create_div.innerHTML;
var create_anchor = document.createElement('a');
document.getElementById('models').appendChild(create_div);
document.getElementById(create_div.id).appendChild(create_anchor);
}
for ex the myJSONObject.model.length is 2
the output is like this
<div id = 'model_id0'>XXXXX<a> </a></div>
<div id = 'model_id1'>XXXXX<a> </a></div> */
but instead of above the output sholud be like this
<div id = model_id0> <a> xxxxxx</a></div>
<div id = model_id1> <a> xxxxxx</a></div>
how to append it inside of the innerhtml
any one plz reply !!!!
two suggestions:
1.) instead of assigning innerHTML to model_idx div assign the model name to its child a. and 2nd instead of appending it to DOM in every loop do it after completing the loop as to minimize frequent the DOM Update ie by:
objContainer = document.createElement('div');
for(....)
{
var create_div = document.createElement('div');
create_div.id = 'model_id'+i;
var create_anchor = document.createElement('a');
create_anchor.innerHTML = myJSONObject.model[i].model_name;
create_div.appendChild(create_anchor);
objContainer.appendChild(create_div);
}
document.getElementById('models').appendChild(objContainer);
I would go along the lines of:
var i = 0,
m = myJSONObject.model,
l = m.length,
models = document.getElementById("models");
for(; i < j; i++) {
var model = m[i];
var create_div = document.createElement("div");
create_div.id = "model_id" + i;
create_div.innerHTML = "<a>" + model.model_name + "</a>";
models.appendChild(create_div);
}
Unless you specifically need to do something to the anchor itself (other than set its innerHTML), there's no need to create a reference to an element for it. If you do need to do something specific to that anchor, then in that case have this, instead:
EDIT: As per your comment, you DO want to do something to the anchor, so go with this (now updated) option - assuming the anchor will always be a child of the div that has the ID you require. The reason "model_id" + i is being put in as a string is because that is exactly what is being passed into the HTML - the document has no clue what "i" is outside of javascript:
var i = 0,
m = myJSONObject.model,
l = m.length,
models = document.getElementById("models");
for(; i < j; i++) {
var model = m[i];
var create_div = document.createElement("div");
var create_anchor = document.createElement("a");
create_div.id = "model_id" + i;
create_anchor.innerHTML = model.model_name;
if(window.addEventListener) {
create_anchor.addEventListener("click", function() {
getModelData(1, this.parentNode.id);
}, false);
} else {
create_anchor.attachEvent("onclick", function() {
getModelData(1, this.parentNode.id);
});
}
create_div.appendChild(create_anchor);
models.appendChild(create_div);
}