0

In this stack there's a solution to select and highlight a whole row from a table using jQuery. I have a callback (see the bottom of my script) when I click a row on the table. The problem is that my table gets generated from data, so the callback does not work on the generated cells. The callback works on the headers, which are not generated.

How to attach the existing callback to the newly generated elements?

<style>
.selected {
  background-color: brown;
  color: #FFF;
}
</style>

<body>
<table id="table" border="1" ContentEditable>
  <tbody id="tablebody">                      
    <tr>
      <th>Date</th>
      <th>Number</th>
    </tr>                      
  </tbody>
</table>
<button onclick="generateTable()">generateTable</button>

<script>
function generateTable() {
  var tbl = document.getElementById('table')
  var tbdy = document.getElementById('tablebody')
  //Table elements
  var arr={Date: "my date", Number:"my number"}
  var tr = document.createElement('tr');
  for (el in arr) {      
    var td = document.createElement('td');
    var t = document.createTextNode(arr[el]);
    td.appendChild(t);
    tr.appendChild(td);
  }
  //append line to tbody
  tbdy.appendChild(tr);
  tbl.appendChild(tbdy);
}


jQuery("#table tr").click(function(){
  console.log("this works only when clocking on the headers <th>")
  jQuery(this).addClass('selected')
    .siblings().removeClass('selected');
});
Community
  • 1
  • 1
aless80
  • 3,122
  • 3
  • 34
  • 53
  • Did you try to change the jQuery("#table tr").click(function()... To: jQuery("#table tr").on('click', function().. – ItayB Sep 20 '15 at 03:02
  • 3
    @ItayB That is exactly the same thing. – epascarello Sep 20 '15 at 03:04
  • @epascarello Delegated events have the advantage that they can process events from descendant elementsthat are added to the document at a later time. From: http://api.jquery.com/on/ – ItayB Sep 20 '15 at 03:09
  • @ItayB I know what delegated events are and yours is NOT a delegated event. – epascarello Sep 20 '15 at 03:10
  • I found it, writing this question helped me. I can wrap the callback in a function and call that function after I generate the td cells. I wish I could answer myself – aless80 Sep 20 '15 at 03:12
  • @epascarello you are right! I mean: jQuery("#table").on('click', 'tr', function().. – ItayB Sep 20 '15 at 03:13
  • 1
    @aless80 or use delegated events and you do not have to do that. – epascarello Sep 20 '15 at 03:14

1 Answers1

4

This is the perfect use-case for the event delegation pattern. That is, instead of defining callbacks on every single element (in your case, every table row) you would define your click callback on a parent element (the table).

This way, when a click event occurs, it will bubble up the dom tree and the parent element can respond to it.

Example:

// Attach a delegated event handler
$( "#table" ).on( "click", "tr", function( event ) {
    event.preventDefault();
    ...
});

This allows us to attach a single click event handler for all current and future table rows.

Anchor
  • 1,331
  • 18
  • 27
  • Thank you, much better than my workaround. One question though: I will study how events work but do I need event.preventDefault() ? – aless80 Sep 20 '15 at 12:14