jptanguay
jptanguay

Reputation: 31

jquery datatables - get a td by column name

I want to add a class to a td in a specific row. I don't want to fuss with numerical indices, but instead access the td by its column's name. In order words, I'd like to do something like this:

for each row in the table where the column "role" contains "some text" 
do add the "red" class to the td in the "email" column.

I've found a way to do it, but I'm not quite satisfied with it; I find it overly complicated. Do someone has something simpler to suggest?

In the example below, I add the class "red" to the td in the column "email" for every row that has "some text" in the "role" column:

tab = $("#myTable").dataTable({
    "data": dataset,
    "columns": [
            { "data": "uid", name: "uid" },
            { "data": "name", name: "name"},
            { "data": "role", name: "role"},
            { "data": "email", name: "email"}
    ]               
});
            
function GetTdByName(row, column_name) {
        var idx = row.nodes().column(column_name + ":name")[0]; 
        var selector = "td:eq(" + idx + ")";
        return row.nodes().to$().find(selector)
}
    
$("#btn").click(function() {
    var ta = $('#myTable').DataTable();
    ta.rows().every(function () {
            if ($.inArray(this.data().role , ["some text", "some other text,"] ) > -1) {    
                GetTdByName(this, "email").addClass("red");
            }
    })
})              

Update

I've found a neater way to do it. Actually, most of this solution can be found in the official doc: column-selector

    ta.rows().every(function () {
        if ($.inArray(this.data().role , ["some text", "some other text,"] ) > -1) {    
            $(ta.column("email:name").nodes()[this.index()]).addClass("red");
        }
    })
        

Upvotes: 3

Views: 3723

Answers (2)

Hmerman6006
Hmerman6006

Reputation: 1913

I think @markpsmith had the correct function type. For your use case I used something similar as the below code:

tab = $("#myTable").dataTable({
    "data": dataset,
    "columns": [
            { "data": "uid", name: "uid" },
            { "data": "name", name: "name"},
            { "data": "role", name: "role"},
            { "data": "email", name: "email"}
    ],
    createdRow: function( row, data, dataIndex ) {
        const bgClass = "red";
        const tdRole = this.api().row(row).column("role:name").nodes();
        const tdEmail = this.api().row(row).column("email:name").nodes();
    
        if ($(tdRole[dataIndex]).text() == "some text") {
            $(tdEmail[dataIndex]).addClass(bgClass);
        }
    }           
});

Since the api() call returns a nodeList you could also use Vanilla on the the indexes by removing $ selector; accessing text() with innerHTML or textContent; and set class with classList.add(bgClass) or className += " " + bgClass.

Upvotes: 0

markpsmith
markpsmith

Reputation: 4918

There is a built-in callback for this: fnRowCallback. It might not be what you want as in your code, you're using a button click to apply the class, but this is how you use fnRowCallback to apply the class as the table renders:

tab = $("#myTable").dataTable({
    "data": dataset,
    "columns": [
            { "data": "uid", name: "uid" },
            { "data": "name", name: "name"},
            { "data": "role", name: "role"},
            { "data": "email", name: "email"}
    ],
   "fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
      if(aData[2] == 'some text'){
         $('td:eq(3)', nRow).addClass('red');
      }
   },
...

Upvotes: 1

Related Questions