4

I have a DataTable into which the values are dynamically inserted. Based on each value of the cell, I need to change its background-color and add some other CSS. I do have a solution here JSFiddle Although,it seems to be slow with large data,is there some other way of achieving this? so that,

  -> The styling does not disappear on sorting the column
  -> It's a little faster than it is now.

Code:

 var t = $('#example').DataTable( {
           "iDisplayLength": 10,
            "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
            "aaSorting": [[1, 'asc']],
            "scrollX": true,
            "scrollCollapse": true,
            "fixedColumns": {"leftColumns": 2},
            "sScrollXInner": "150%",
            "fixedHeader": true,
            "rowCallback": function (row, data) {
               for (var p = 2; p < data.length; p++) {
                if(data[p] == "red"){
                   $('td:eq('+p+')', row).addClass('highlight1');
                }
               }
                if ($.inArray(data.DT_RowId, selected) !== -1) {
                    $(row).addClass('selected');
                }
            },
        } );
        // $('.searchable').tablesearcher({ 'input': $in });
        var selectedSPFName = $("#spfspan").text();

    $.each(md, function(i, x){
    var thisRow = [];
    thisRow.push('<u><a target="_blank" href="' + x.Data[0].Link + '">' + x.Data[0].Value + '</a></u>');
      for(var k=1;k<x.Data.length;k++){
        thisRow.push(x.Data[k].Value);
      }
        t.row.add(thisRow).draw();
    }); 

Any suggestions on this highly appreciated! Thank you!

Apeksha
  • 259
  • 1
  • 3
  • 15

2 Answers2

1

Performance issue:

As pointed out in the other answer, you shouldn't be calling draw inside a loop. Anything that involves manipulating the DOM is likely to be expensive, and should be used as few times as possible. So you manipulate the data inside the loop, then render:

$.each(md, function(i, x) {
    ....
    t.row.add(thisRow);
});
t.draw();

I believe this will speed things up a lot, and should be enough. But this approach is going to iterate over the whole table at once. In case you have a very long table, you could use the drawCallback (https://datatables.net/reference/option/drawCallback) instead of rowCallback, and manipulate only visible rows, by getting the current page:

"drawCallback": function( settings ) {
    var api = this.api();
    var visibleRows = api.rows( {page:'current'} ).data();
    // manipulate rows here
}

Styling issue

This one is simple to fix. Your approach is actually working, but when you sort the rows, there is a class being added .sorting_1 to the cell. This class has a strong selector, and is overriding your background color definition:

table.dataTable.display tbody tr.odd > .sorting_1,
table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {
    background-color: #f1f1f1;
}

Your options are:

1 - be more specific than the rule above:

table.dataTable.display tbody tr.odd > td.highlight1{
 background-color: #e6ffe6 ;
} 

2 - add an !important to the style definition:

td.highlight1{
 background-color: #e6ffe6 !important;
} 

Checkout your your updated fiddle - https://jsfiddle.net/atexooaq/2/

Hugo Silva
  • 6,748
  • 3
  • 25
  • 42
0

My guess is that calling draw after each row.add() is the killer. Try calling draw once after all the rows have been added.

$.each(md, function(i, x) {
    ....
    t.row.add(thisRow);
});
t.draw();
JonSG
  • 10,542
  • 2
  • 25
  • 36
  • Yes @JonSG, I did try the solutions you provided. It seems to partially work! Only the
    appended to each gets the background color and not the whole cell. Here is the [JSFiddle](https://jsfiddle.net/povhb3zs/). Is there a way to color the whole cell
    – Apeksha Jul 12 '16 at 22:07
  • 1
    @JonSg - How is this different from adding a class? `td div[data-color="red"] { background-color: red; }` === `td div.redBackground { background-color: red; }` – Hugo Silva Jul 12 '16 at 23:14
  • There might not be any difference between them. The main point was more to experiment with the application of a style directive as part of data loading if paging is slow. Ultimately, if it is slow to load / display it is probably the draw call on each row.add() that is the main issue. – JonSG Jul 13 '16 at 00:36
  • The suggestion by @HugoSilva below to use the drawCallback seems like a better solution to the additional formatting on data load. I'm going to prune that out of my answer. You can use the drawCallback to add the the appropriate class and even set up your link rather than on rowCallback. – JonSG Jul 13 '16 at 12:10
  • Thank you @Hugo Silva for your suggestions. I did try to work with drawCallbackbut it does not seem to update those CSS changes. [JSFiddle](https://jsfiddle.net/nfdr88e6/). Can someone please suggest me on where I am going wrong? – Apeksha Jul 13 '16 at 20:24
  • @Apek - you were getting it right, but only for one line. You were missing iterating over all lines off the table. Check out your fiddle updated - https://jsfiddle.net/hugofelp/nfdr88e6/2/ BTW, did you see there is a working fiddle in my answer, with minimum changes to your original approach? – Hugo Silva Jul 13 '16 at 21:15
  • @Hugo Silva Thank you for correcting that for me. how different is styling(CSS) in `drawCallback` different from styling in `createdRow`. Does this have an effect on the performance?Any idea on this? – Apeksha Jul 13 '16 at 21:40
  • @Apek - The idea with drawCallback is that you get only what is visible every time the table draws (draw = changing page, sorting, filtering, etc), and change styles of as many rows you have per page (which is 10 in the fiddle). Using createdRow, you will manipulate styles only once, but for every row in the table (60 in the fiddle). So it really depends on your real case. Say you have a table with a million rows: use `drawCallback`. Now, if your table has like 100 rows, I think you can use `createdRow` without noticing any difference in performance. – Hugo Silva Jul 13 '16 at 22:07
  • Now, the ideal solution in my opinion, would be adding styles in the same loop you are creating the rows... but that is a different topic, I think you've got all the answers for this question already. – Hugo Silva Jul 13 '16 at 22:11
  • My original answer did that, if you wanted you could so that. Probably need to clear out some pading from the table elements – JonSG Jul 14 '16 at 14:02