1

I would like to be able to click anywhere on a row and get the contents of its first cell, regardless of where I click. Note that this is a dynamically generated table and consists of <th>, <tr>and <td> elements exclusively (no <tbody>), and that therefore none of the rows within said table have an id. The commented part works by itself, so why can't I get the text from that first cell? Or even just the contents of the row would be a good start. Is there something wrong with my selectors anywhere in the function where I'm //trying to get the contents? I have no clue what's wrong with this.

//  Build HTML Table
function buildHtmlTable(portalData, tablename) {
    var columns = [];
    var headerTr$ = $('<tr/>');
    var n = 0;
    if (tablename == "order-table") {
        document.getElementById("dist-name").innerText = JSON.parse(JSON.stringify(portalData[0], null, 2))["Company Name"];
        n = 1;
    }
    for (var i = 0 ; i < portalData.length ; i++) {
        var rowHash = portalData[i];
        for (var key in rowHash) {
            if ($.inArray(key, columns) == -1) {
                columns.push(key);
                headerTr$.append($('<th/>').html(key));
            }
        }
    }
    $('#' + tablename).append(headerTr$);
    for (i = 0 ; i < portalData.length ; i++) {
        var row$ = $('<tr/>');
        for (var colIndex = n ; colIndex < columns.length ; colIndex++) {  // n is how many columns to drop, based on table name
            var cellValue = portalData[i][columns[colIndex]];
            if (cellValue == null) {
                cellValue = "";
            }
            row$.append($('<td/>').html(cellValue));
        }
        $('#' + tablename).append(row$);
    }

    // Drop unnecessary columns
    for(i = 0 ; i<n; i++) {
        $("#order-table").find('td,th').first().remove();
    }

    //Trying to get the contents
    $(function(){
        $("#order-table td").click(function() {     

            // var column_num = parseInt( $(this).index() ) + 1;
            // var row_num = parseInt( $(this).parent().index() );    

            // alert( "Row_num = " + row_num);   
            var column = $(this);
            var row = ($(this).parent());

            alert(row.innerText);
            alert(column.innerText);
        });
    });
}
cryophoenix
  • 171
  • 10

1 Answers1

1

You can bind a click event to an existing element on the page and get the value of the first cell using DOM navigation. So, for example, if your table already existed on the page and you want to bind a click event to dynamically added rows, you can reference the table element:

$(document).ready(function() {
  $('table').on('click', 'tr', function() {
    var value = $(this).find('td:first-child').text();
   //do something with value
  });
});

Demo

In your case, it looks like you're dynamically adding the table itself to the page. In that case, you can bind to document and reference the id of the dynamically added table:

$(document).ready(function() {
  $('document').on('click', '#order-table tr', function() {
    var value = $(this).find('td:first-child').text();
   //do something with value
  });
});

If you want this click event on all tables, you can do:

$(document).ready(function() {
  $('document').on('click', 'table tr', function() {
    var value = $(this).find('td:first-child').text();
   //do something with value
  });
});
devlin carnate
  • 8,309
  • 7
  • 48
  • 82
  • While yes, I'm dynamically adding it, it's a single page where divs are being hidden and unhidden. In fact, the table isn't generated until the user logs in. Thus a $(document).ready function won't work... In other words, if it gets an OK response from the server, then it builds the table. THEN it needs to add the listener. In other words, your second solution sounds right. But it doesn't let me even pop an alert. Your first example has a tbody, which this table does NOT have. – cryophoenix May 03 '18 at 16:10
  • @cryophoenix It doesn't matter if the table is dynamic. The document element is NOT dynamic (elements within the DOM are dynamic, but the document itself is not) and therefore, you can use it as an anchor of sorts for your listeners. More here: https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – devlin carnate May 03 '18 at 16:28
  • Do I need to place this logic inside the existing table creation function as an anonymous or do i need to make it a named function that I call during the table creation process? Remember, the table tags are created and the table is empty (no `th`, `tr`, nothing) when the document loads. Just a `
    ` spot. so when the document is ready, that would apply all this to just that empty table prior to creation of rows, would it not?
    – cryophoenix May 04 '18 at 12:42
  • @cryophoenix : Check out `delegate event` : https://learn.jquery.com/events/event-delegation/ . I'll work up a demo to show you. – devlin carnate May 04 '18 at 16:03
  • @cryophoenix : I've updated the link to the Demo in my answer with an example that shows dynamic rows. – devlin carnate May 04 '18 at 16:21