Reputation: 65
I want to create a script, which would provide possibility of making food table with nutrients counting. Lets say a daily menu. When user clicks buttons, ingredients are adding to table. There are + and - buttons in the line of ingredient to change amount of it by 1.
html:
<div class="menuContainer">
<div class="foodListContainer">
<div class="row"></div>
</div>
<div class="buttonsContainer">
<button value="100,g.,12.6,2.6,68,355">Buckweat</button>
<button value="1,ps.,6.3,5.7,0.35,78.5">Egg</button>
<button value="1,sp.,2.8,3.2,4.7,58">Butter</button>
<button value="100,g.,12.6,2.6,68,355">Meat</button>
</div>
js:
$(document).ready(function () {
//When user click a button
$(".buttonsContainer button").click(function () {
//catching the name of food
var choosenFood = $(this).text();
//catching the value of pressed button with info
//about this food and making an array with it
var value = $(this).val();
var arr = value.split(',');
//insert div's with info from array
$($.parseHTML(
'<div class="name">' + choosenFood + '</div><button class="up">+</button><div class="value">' + arr[0] + '</div><div class="unit">' + arr[1] + '</div><button class="down">-</button><div class="protein">' + arr[2] + '</div><div class="fat">' + arr[3] + '</div><div class="carbs">' + arr[4] + '</div><div class="kkal">' + arr[5] + '</div><br>')).appendTo(".row");
//trying to change value
$('.down').click(function () {
$(this).prev().prev(".value").html(function (i, val) {
return val * 1 - 1;
});
});
$('.up').click(function () {
$(this).next(".value").html(function (i, val) {
return val * 1 + 1;
});
});
});
The problem starts when there are 2 and more rows in the table. The more rows, the more + and - buttons change value. You better look at it here: https://jsfiddle.net/ts3n35bq/
I assume, that there is some problem with scopes. Probably, the crucial mistake is to call "up" and "down" actions right from "appendTo" action, and it seems like this functions repeated themselves in every row, until the end. But when I try to remove them from there, they don't work at all.
I will appreciate any advice or help. Thanks!
Upvotes: 1
Views: 93
Reputation: 116
Each time you click to add a div to your table you call $('.down').click()
which binds the event to all the existing buttons with the "down" class. Adding more than a single row makes it so that for a single click event you have multiple handlers attached to the preexisting buttons.
You can easily fix this without changing much of your code. Instead of appending the new row directly save it to a variable first and add the click handler to the down/up element inside it:
var rowString = '<div class="name">' + choosenFood + '</div><button class="up">+</button><div class="value">' + arr[0] + '</div><div class="unit">' + arr[1] + '</div><button class="down">-</button><div class="protein">' + arr[2] + '</div><div class="fat">' + arr[3] + '</div><div class="carbs">' + arr[4] + '</div><div class="kkal">' + arr[5] + '</div><br>';
var newRow = $($.parseHTML(rowString));
newRow.filter(".down").click( function () {
$(this).prev().prev(".value").html(function (i, val) {
return val * 1 - 1;
});
});
newRow.filter(".up").click(function () {
$(this).next(".value").html(function (i, val) {
return val * 1 + 1;
});
});
newRow.appendTo(".row");
Upvotes: 0
Reputation: 9123
Instead of:
$(".buttonsContainer button").click(function () {
...
});
Use:
$(document).on('click', '.buttonsContainer button', function() {
...
});
Upvotes: 0
Reputation: 15846
$(".buttonsContainer").on('click','button',function (){
//your code
});
Upvotes: 0
Reputation: 21
Use unbind on click function
$('.down').unbind().click(function () {
$(this).prev().prev(".value").html(function (i, val) {
return val * 1 - 1;
});
});
$('.up').unbind().click(function () {
alert($(this).next(".value").attr('id'));
$(this).next(".value").html(function (i, val) {
return val * 1 + 1;
});
});
Upvotes: 1
Reputation: 500
This should work for you.
$(document).ready(function () {
$('body').on('click', '.down', function() {
$(this).prev().prev(".value").html(function (i, val) {
return val * 1 - 1;
});
});
$('body').on('click', '.up', function() {
$(this).next(".value").html(function (i, val) {
return val * 1 + 1;
});
});
//When user click a button
$(".buttonsContainer button").click(function () {
//catching the name of food
var choosenFood = $(this).text();
//catching the value of pressed button with info about this food and making an array with it
var value = $(this).val();
var arr = value.split(',');
//insert div's with info from array
$($.parseHTML(
'<div class="name">' + choosenFood + '</div><button class="up">+</button><div class="value">' + arr[0] + '</div><div class="unit">' + arr[1] + '</div><button class="down">-</button><div class="protein">' + arr[2] + '</div><div class="fat">' + arr[3] + '</div><div class="carbs">' + arr[4] + '</div><div class="kkal">' + arr[5] + '</div><br>')).appendTo(".row");
//trying to change value
});
});
Upvotes: 2