Diasline
Diasline

Reputation: 635

Use keyup function in multiple table row

I have a table that i can insert new row after click on a button. I would like to use a keyup function to make calcul between td values. My issue is the keyup function works for the first line, after I insert a new line the function affects the new line and previous line. How can I create the function to use it separately for each new row added ?

Thanks in advance.

    <button type="button" class="add-row" >Add</button>
<table>
<tr>
<td>Amount</td>
<td>Price</td>
<td>Result</td>
</td>
</tr>
<tr>
<td class='amount' contenteditable='true'></td>
<td class='price' contenteditable='true' onkeyup='calculfac()'></td>
<td class='result'></td>
</tr>
</table>

<script>
//Add new row on click
$(".add-row").click(function(){
var markup = "<tr><td class='amount' contenteditable='true'></td><td class='price' contenteditable='true' onkeyup='calculfac()'></td><td class='result'></td></tr>";
$("table tbody").append(markup);
});

//Calcul

function calculfac() {
var amount= $('.amount').text();
var price= $('.price').text();
var mult = amount * price;
var result = Math.round(mult).toFixed(2);
$('.result').text(result);
}

Upvotes: 1

Views: 2043

Answers (2)

Wild Beard
Wild Beard

Reputation: 2927

You're almost there in your snippet. You can specify a parent when using creating jQuery selector: $('.selector', parent) where parent can be a jQuery object or another selector itself. See the snippet below:

function calculfac() {

  const parent = $(this).parent('tr');
  const amount = $('.amount', parent).text();
  const price = $('.price', parent).text();
  const result = Math.round(amount * price).toFixed(2);
  $('.result', parent).text(result);

}

Additionally I would remove onkeyup="calculfac()" from your elements and use a jQuery selector and pass in your function as the handler. This allows us to trigger the event on each editable zone instead of just the price. If we do not do this a user could set the price and later update the amount but the total would remain the same before the change. See the snippet below:

$('tbody').on('keyup', '[contenteditable="true"]', calculfac);

A key difference about the above snippet is we're using .on. Since the new tr's are generated by your click handler a traditional selector of tr [contenteditable="true"] won't work as the new tr from your handler do not yet exist in the DOM at the time the selector is ran. .on allows you to filter a wider range of elements. So we're selecting tbody and on keyup of matching contenteditable=true elements we're passing the event to our calculfac function.

Here is the complete Fiddle

Upvotes: 2

ElBrm
ElBrm

Reputation: 344

That's because you're working with classes. Your code can't recognize which class value should change. It will change all the values of all classnames.

You can fix it by using the .each() function. You want to change the contents of the <td> tags in almost each <tr> tag. Not every <tr> tag so we can use a class to tell which <tr> we mean. So, lets go:

Step 1 - Add the class '.tr' at the tags that have the children that you want to change.

<tr class="tr"> 

Step 2 - Add the '.tr' class to the 'Add new row' - function

//Add new row on click
$(".add-row").click(function(){

    var markup = "<tr class='tr'><td class='amount' contenteditable='true'></td><td class='price' contenteditable='true' onkeyup='calculfac()'></td><td class='result'></td></tr>"; //Add '.tr' class

    $("table tbody").append(markup);

});

Step 3 - Tell the classes that you want to get/change the values of them on each .tr class.

function calculfac() {

  $('.tr').each(function(){ //Each .tr class
        var amount= $('.amount', this).text(); //The .amount class of 'this' .tr class
        var price= $('.price', this).text(); //The .price class of 'this' .tr class
        var mult = amount * price;
        var result = Math.round(mult).toFixed(2);
        $('.result', this).text(result); //The .results class of 'this' .tr class

  });

}

Example

Check out the JSFiddle: https://jsfiddle.net/z9qsyzr8/15/

Upvotes: 1

Related Questions