1

I would like my js to add a row every time the user adds their initials. My code works the first time the user enters their initials, a new row is created under the first row, but then does not add anymore. I am not sure what i need to do.

My JS code:

(function(){
    var counter = 1;
    $("#preformedBy").change(function(){
        $('#timeStamp').html(new Date().toLocaleString());
        $('#harvestedCannabis > tbody:last-child').append('<tr><td><input type="number" id="toteNum" readonly></td><td><input type="number" step=".1">' + 
        '</td><td><input type="number" step=".1"></td><td><input type="number" step=".1"></td><td><input type="number" step=".1"></td><td>' + 
        '<input type="text"></td><td><input type="text" id="preformedBy"></td><td id="timeStamp"><input type="text" readonly></td></tr>');
        counter = counter + 1;
        $('#toteNum').html(counter)
    })
});

My HTML:

<table id="harvestedCannabis">
                <tr>
                    <th>Tote #</th>
                    <th>Flowers</th>
                    <th>Trim A</th>
                    <th>Trim B</th>
                    <th>Waste</th>
                    <th>Originating Line(A,B,C)</th>
                    <th>Preformed By</th>
                    <th>Time Stamp</th>
                </tr>
                <tr>
                    <td id="toteNum"><input type="number" value="1" readonly></td>
                    <td><input type="number" step=".1"></td>
                    <td><input type="number" step=".1"></td>
                    <td><input type="number" step=".1"></td>
                    <td><input type="number" step=".1"></td>
                    <td><input type="text"></td>
                    <td><input type="text" id="preformedBy"></td>
                    <td id="timeStamp"><input type="text" readonly></td>
                </tr>
            </table>    

I would like the table to keep appending new row as many times as the user requires, automatically after they insert their initials

Mike
  • 129
  • 1
  • 9
  • `id`s have to be unique across the document, you are repeating them when you insert new rows. Also, take a look at [this question](https://stackoverflow.com/questions/203198) and the [jQuery reference](https://learn.jquery.com/events/event-delegation/). – msg Aug 20 '19 at 18:06
  • @msg yes i did notice the ids. I changed them to classes. Thank you though – Mike Aug 20 '19 at 18:40

4 Answers4

2

You have two main issues with your code. I'll explain them, but first take a look at this fiddle I made with your code, this version actually works: https://jsfiddle.net/49Ln0qcf/#&togetherjs=2hdIlfBaC0

So now lets explore where you went wrong:

1. You're listening to an ID attribute for your onChange event. It works the first time around because at that point in time you only have one element with id="preformedBy", but after you add your second row you then have TWO elements with the same ID. jQuery is listening to the first instance of the ID in the dom, thus your additional input fields are not being listened to. So, replace your id attribute with a class, then your .preformedBy selector will work past your second iteration.

2. Taking the step above alone will not fix your code. To get more than the first iteration to work, you'll need to listen to the parent element of your .preformedBy class. In your code, you're listening to preformedBy directly like so:

$("#preformedBy").change(function(){

The problem here is that on page load, jquery is only aware of the dom elements that exist on page load, thus the first and only instance of preformedBy. So jQuery will continue to listen to that element and ONLY that element because it knows nothing of the elements you've added to the dom AFTER page load. In order to get jQuery to listen to ALL instances of preformedBy, you need to listen to a parent selector. Notice in my code, I'm listening to preformedBy like so:

$("#harvestedCannabis").on('change', '.preformedBy', function(){

The key difference is that my code listens to change events on the parent element, but specifically listens to any and all occurrences of '.preformedBy' within that parent element. As where your code is listening to a unique element with the preformedBy selector.

I hope this helps.

Finalized code that works: html:

<table id="harvestedCannabis">
                <tr>
                    <th>Tote #</th>
                    <th>Flowers</th>
                    <th>Trim A</th>
                    <th>Trim B</th>
                    <th>Waste</th>
                    <th>Originating Line(A,B,C)</th>
                    <th>Preformed By</th>
                    <th>Time Stamp</th>
                </tr>
                <tr>
                    <td id="toteNum1"><input type="number" value="1" readonly></td>
                    <td><input type="number" step=".1"></td>
                    <td><input type="number" step=".1"></td>
                    <td><input type="number" step=".1"></td>
                    <td><input type="number" step=".1"></td>
                    <td><input type="text"></td>
                    <td><input type="text" class="preformedBy"></td>
                    <td id="timeStamp1"><input type="text" readonly></td>
                </tr>
            </table>  

jQuery:

var counter = 1;
$("#harvestedCannabis").on('change', '.preformedBy', function(){
  $('#timeStamp'+counter).html(new Date().toLocaleString());
  $('#harvestedCannabis > tbody:last-child').append('<tr><td><input type="number" id="toteNum'+(counter + 1)+'" readonly></td><td><input type="number" step=".1">' + 
                                                    '</td><td><input type="number" step=".1"></td><td><input type="number" step=".1"></td><td><input type="number" step=".1"></td><td>' + 
                                                    '<input type="text"></td><td><input type="text" class="preformedBy"></td><td id="timeStamp'+(counter + 1)+'"><input type="text" readonly></td></tr>');
  $('#toteNum'+(counter + 1)).val(counter + 1);
  counter = counter + 1;
});
kenef
  • 183
  • 10
0

Your are changing all this element #toteNum with counter value

<td id="toteNum"><input type="number" value="1" readonly></td>

When you create a new element you need to rebind the listeners.

When your code works, your HTML will have 2 #preformedBy elements, you may have unique ids on the same page.

Rafael Lopes
  • 463
  • 3
  • 8
0

Try the insertRow() and insertCell() methods.

According to W3Schools example:

https://www.w3schools.com/jsref/met_table_insertrow.asp

Welyngton Dal Prá
  • 758
  • 1
  • 10
  • 19
0

Remove the id from your html and js code and use a class selector to trigger the change function, then it should work.

dicemaster
  • 1,203
  • 10
  • 22