3

So not sure exactly what's going on but can make a few guesses.

My understanding of .on() is that it is meant to attach to all dynamically added elements. But it doesn't seem to be working here. Or if I've misunderstood that, then the way I'm implementing is not working.

On document load, I call this:

$("#orderBox tbody tr").on( 'click', function ( e ) {
    selectRow($(this));
} )

Where selectRow() toggles the class on a tr element (code below).

When the document is loaded, the table is empty, so new rows are added by the addTableRow() function, which just appends a tr to the tbody. Once that tr has been added, clicking it does nothing. So I moved the .on() event from document load to after the new row has been created.

function redrawOrderBox(){
    $("#orderBox tbody tr").on( 'click', function ( e ) {
        selectRow($(this));
    } )
}

function selectRow(row){
    row.toggleClass('selected');
}

function addTableRow(items){

    newRow = "<tr>";
    newRow += "<td class=\"hide\">"+items[0]+"</td>"
    newRow += "<td>"+items[1]+"</td>"
    newRow += "<td>"+items[2]+"</td>"
    newRow += "<td>"+items[3]+"</td>"
    newRow += "<td>"+items[4]+"</td>"
    newRow += "<td class=\"hide\">"+items[5]+"</td>"
    newRow += "<td class=\"hide\">"+items[6]+"</td>"
    newRow += "<td class=\"hide\">"+items[7]+"</td></tr>";
        
    $('#orderBox tbody').append(newRow);
    redrawOrderBox();
}

This kinda works. The class "successfully" toggles on it seems every second row. After adding three rows, from what I can tell in inspector or when sticking in an alert(), it fires successfully on the third row, then fires twice on the second row when clicked (giving the appearance that nothing happened). On the first row, it fires three times, which gives the impression that it worked fine.

So I'm calling the click event multiple times - probably because I'm attaching it 3 times.But if I try to use it in document load, nothing happens.

What I intend to do is modify the redraw() function to strip the click event before reattaching it. But it just feels like the wrong way to go about it.

What's the best way to do this?

Josh
  • 186
  • 1
  • 3
  • 17
  • I think your function called multiple time when block of code executed. You have to debug that block of code. – Parth Raval Nov 12 '20 at 05:06
  • It is attached multiple times. I can fix that by adding `$("#orderBox tbody tr").off('click');`but I just thought that .on() attached to dynamically added items. But perhaps I was just mistaken – Josh Nov 12 '20 at 05:08
  • Yes. Exactly You just need to check the code once again and then you will find that you have used that same function multiple time by removing that you will able to solve this issue. – Parth Raval Nov 12 '20 at 05:21
  • Does this answer your question? [Event binding on dynamically created elements?](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – freedomn-m Nov 12 '20 at 09:12

1 Answers1

3

For jquery on, you effectively need 2 selectors, the parent and the child. You attatch on to the parent with a parameter as a selector to determine decendants that fire the event.

Use this instead:

$("#orderBox tbody").on( 'click', 'tr', function ( e ) {
    selectRow($(this));
} )

Existing trs and those added dynamically will now correctly fire the event handler.

Jon P
  • 19,442
  • 8
  • 49
  • 72