'JQUERY dynamically created table. Trying to hide entire column

This is creating my table and working - It creates a table and I am going to have it check a list to hide columns. For testing purposes I am trying to hide the colun "Proj_Type" it does hide the header but does not hide the actual column of data. I want the entire thing to hide.

  function createTab(Name, id) {
        var $button = $('<button/>', {
            'class': 'tablinks',
            'onclick': 'return false;',
            'id': name,
            text: Name,
            click: function () {
                return false;
            }
        });
        var $div = $('<div>').prop({
            id: Name,
            'name': id + 'MKTTAB',
            className: 'tabcontent'
        })
        var $table = $('<table/>', {
            'class': 'GRD1',
            id: id + "GRDMKTLIST",
        }
        )
        $table.append('<caption>' + Name + '</caption>')
        var $tbody = $table.append('<tbody />').children('tbody');
        $tbody.append('<tr />').children('tr:last');
        $.ajax({
            type: "POST",
            url: "../WebMethods/MarketPersuitMethods.aspx/GetQueryInfo",
            data: {},
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            async: false,
            success: function (d) {
                var data = $.parseJSON(d.d);
                var colHeader = Object.keys(data[0]);
                for (var i = 0; i < colHeader.length; i++) {
                    if (colHeader[i] != "notes") {
                        $tbody.append("<th>" + colHeader[i] + "</th>");
                    }
                }
                //sets new line
                $tbody.append('<tr />').children('tr:last')
                for (var i = 0; i < data.length; i++) {

                    for (var j = 0; j < colHeader.length; j++) {
                        if (colHeader[j] != "notes") {
                            $tbody.append('<td>' + data[i][colHeader[j]] + '</td>');
                        }
                    }
                    $tbody.append('<tr />').children('tr:last')
                }

                setTimeout(function () {
                }, 1000);
            }

        });
        $($table.find('th')).each(function () {
            var indextest = $(this).index() + 1;
            
if ($(this).text() == "Proj_Type") {
                $('[id*=GRDMKTLIST] td:nth-child(' + indextest + '),th:nth-child(' + indextest + ')').hide();
            }

        })
        $button.appendTo('#tabs');
        $table.appendTo($div);
        $div.appendTo('#TabbedMktList');
   
       
    }
 

However, on the bottom where i have

if ($(this).text() == "Proj_Type") {
                $('[id*=GRDMKTLIST] td:nth-child(' + indextest + '),th:nth-child(' + indextest + ')').hide();
            }

This only hides the header and I am trying to hide the entire column TD included.



Solution 1:[1]

There are two main issues:

  • $('[id*=GRDMKTLIST]

will look in the DOM, but your $table has not yet been added to the DOM, so does nothing. Use $table.find(... to use the $table variable in memory.

  • $tbody.append('<td

will append the td (and equivalent code for th) to the tbody - but these should be in a tr.
The browser will do some "magic" and see an empty <tr></tr> and put a new row in for you, but selectors for tbody > tr > td won't work. This also means there's only a single :nth-child(n) per n, not per row (as all cells across all rows are siblings).

You can add a new row to $tbody and return the new row by using .appendTo

$tr = $("<tr>").appendTo($tbody);

then add the th/td to $tr and not $tbody

$tr.append('<td...`

Regarding the selector for $table.find("td,th") you don't need the th part as you're looping th and it's already this, so you can do:

$(this).hide();
$table.find('td:nth-child(' + indextest + ')').hide();

Also make sure you only create tr as you need it. Your code create a tr before the data row loop and inside the data row loop, leaving an empty tr.

for (var i = 0; i < data.length; i++) {
  $tr = $("<tr>").appendTo($tbody);
  for (var j = 0; j < colHeader.length; j++) {
    if (colHeader[j] != "notes") {
      $tr.append('<td id=' + colHeader[j] + '>' + data[i][colHeader[j]] + '</td>');
    }
  }
}

Also updated in the fiddle: https://jsfiddle.net/n168ra2g/3/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 freedomn-m