4

Problem Statement:
I have a table with thead created statically, and 'tr/td' inside the tbody created dynamically. What I have to achieve is that when the user clicks anywhere on the table, I need to get the val() of the first column of the row which was clicked.

To test this I am binding a click event using on to the parent element class, i.e. class for tbody. And, I am trying to update the text in the First column td:first of the clicked row, e.g. clicked.

However, somehow the events are not being caught. Here is the extract from the JSfiddle.

HTML:

<table class="table" id="table-id">
    <thead>
        <tr class="table-header">
            <th class="edit">Edit</th>
            <th class="name">Name</th>
            <th class="status">Status</th>
        </tr>
    </thead>
    <tbody class="table-body" id="table-body-id">
    </tbody>
</table>

TABLE CREATION

var container = $('.table-body');
['A', 'B'].forEach(function(index){
    $('<tr>', {class: 'table-row', id: 'table-row-id-'+index}).appendTo(container);
    $('<td />', {class: 'edit', id: 'edit-id-'+index, value: index}).appendTo(container);
    $('<td />', {class: 'name', id: 'name-id-'+index, text: 'Mr. '+index}).appendTo(container);
    $('<td />', {class: 'status', id: 'status-'+index, text: 'MSc'}).appendTo(container);
    $('</tr>').appendTo(container);
});

BINDING CLICK EVENT

$("#table-body-id").on("click", "tr", function(){
    alert($(this).find('td:first').val());
    $(this).find('td:first').text('clicked');
});

I have looked at plethora of threads on stack-overflow and after that I wrote the above code. One working JS-Fiddle example.

However, it is not working for the code that I have written above. Could somehow please point me out as to why is not working and how to fix it?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
wierdmaster
  • 51
  • 1
  • 1
  • 3
  • Not sure if it's a C+P error, but your javascript accesses `#table-body-id` and your table has an id of `table-id`. – Luke Oct 23 '15 at 15:51

2 Answers2

4

Your appends were all messed up. Here is your code corrected/working.

var container = $('.table-body');
//Create an empty container
var $trs = $();
['A', 'B'].forEach(function(index) {
    //Create TR and append TDs to it
    var $tr = $('<tr/>', {class: 'table-row', id: 'table-row-id-'+index});
    $tr.append(
        $('<td />', {class: 'edit', id: 'edit-id-'+index, value: index}).
        add($('<td />', {class: 'name', id: 'name-id-'+index, text: 'Mr. '+index})).
        add($('<td />', {class: 'status', id: 'status-'+index, text: 'MSc'}))
    );
    //Add each tr to the container
    $trs = $trs.add($tr);
});

//Append all TRs to the container.
container.append($trs);

$(".table-body").on('click', 'tr', function() {
    alert( 'Clicked row '+ ($(this).index()+1) );
    //Use .text() as td doesn't have method .val()
    //Empty first time as the td:first has no text until clicked.
    alert( $(this).find('td:first').text() );
    $(this).find('td:first').text('clicked');
});

A demo

lshettyl
  • 8,166
  • 4
  • 25
  • 31
  • Awesome. That worked. :-) Thanks a zillion. Now I know that I should check my HTML. Just seeing it rendered as expected may not be right. :-) – wierdmaster Sep 02 '15 at 23:23
  • Why wouldn't I? That's perfect. :-) If you are talking about voting-up the answer, somehow I need '15 reputation' for my vote to be publicly visible. I am fairly new to SO. :-( – wierdmaster Sep 06 '15 at 17:04
2

It is not ideal to attach click events through the body, but in some occasions I do this and it works great.

$("body").on("click", "#table-body-id tr", function(){
    alert($(this));
});
William Howley
  • 483
  • 4
  • 20