Can we use rowCallback function after rendering the table

Can we use rowCallback function after rendering the table

Vishakha-92Vishakha-92 Posts: 15Questions: 0Answers: 0
edited May 2022 in Free community support

I'm working on a functionality to highlight duplicate column data in different rows in a datatable. I saw the examples with rollcallback function. However, since there's a couple of functions running at the time of initialization like sorting, I want to highlight after rendering by using table variable. Is there a possibility.
This is what I referred from the docs

table = $('#tablename").DataTable({
      "rowCallback": function( row, data, index ) {
        var allData = this.api().column(1).data().toArray();
        if (allData.indexOf(data[1]) !== allData.lastIndexOf(data[1])) {
          $('td:eq(1)', row).css('background-color', '#3eaf14');
        }
      },

Can I use the "table" initialization object to compare after initialization is finished

Replies

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    Does the rowCallback function not work? I don't understand how sorting would affect this functionality. Please describe the problem you are trying to solve.

    rowCallback will run for each row displayed on the page. By default this will be 10 rows. And it will run for each draw event.

    You might look at doing the same thing with createdRow. In most cases, will run for all rows in the table during initialization. There are a couple differences noted in the docs.

    However if you want to loo through all the rows after initialization you can use rows().every() in initComplete. You will need to use this.api() instead of the table variable to get the API. See this column search example to see how to use this.api().

    Kevin

  • Vishakha-92Vishakha-92 Posts: 15Questions: 0Answers: 0

    Using the rowcallback is not working properly, it's highlighting rows that are not equal. My table displays data after sorting in the following way

    345
    123
    123
    456
    456
    789
    789
    561
    Rowcallback highlights all this data but also highlights data that doesn't have duplicates. Eg: 345 & 561 are also highlighted despite them appearing only once

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    The sorting doesn't matter. This will generate the same data no matter how the table is sorted:

    var allData = this.api().column(1).data().toArray();
    

    Have you performed any debugging of the rowCallback to see what is happening?

    I posted your code here with sorting on the column being checked and it works:
    http://live.datatables.net/qifeyeqi/1/edit

    We will need more information to help debug. Please post a link to your page or a test case replicating the issue so we can take a look.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • Vishakha-92Vishakha-92 Posts: 15Questions: 0Answers: 0

    Okay, I debugged and realized it's doing so because of filtering. I'm using a default filter during initialization and I want the rollback to work according to the filter applied. It's highlighting rows that don't match the filter. That's my issue.

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    Try using the selector-modifier of {search:'applied'}, like this:

    var allData = this.api().column(1, `{search:'applied'} ).data().toArray();
    

    Kevin

  • Vishakha-92Vishakha-92 Posts: 15Questions: 0Answers: 0

    This did not work, this is what I'm doing. The default filter is applied via a dropdown on some other column

    ```
    table = $('#tableName).DataTable({
    "rowCallback": function( row, data, index ) {
    var allData = this.api().column(1, {search:'applied'} ).data().toArray();
    if (allData.indexOf(data[1]) !== allData.lastIndexOf(data[1])) {
    $('td:eq(1)', row).css('background-color', '#3eaf14');
    }
    },
    'orderCellsTop': true,
    'pageLength': pageLength,
    "order": [[ orderColumn, orderBy ]],
    "processing": true,
    "orderClasses": false,
    "deferRender": true,
    "responsive": true,
    dom: 'Blfrtip',
    "fixedHeader": {
    header: true,
    },
    "columnDefs":columnDefsArray,
    //"columns":columnsArray,
    buttons: buttonsArray,
    initComplete: function () {
    var api = this.api();
    count = 0;

          this.api().columns([4,6]).every(function () {
            var column = this;
            var title = column.header();
            title = $(title).html().replace(/[W]/g, '-');
    
            var select = $('<select id="select-' + title + '" class="select2"></option></select>')
              .appendTo('#selectTriggerFilter')
              .on('change', function () {
                var data = $.map($(this).select2('data'), function (value, key) {
                  return value.text ? '^' + $.fn.dataTable.util.escapeRegex(value.text) + '$' : null;
                });
                if (data.length === 0) {
                  data = [""];
                }
    
                //join array into string with regex or (|)
                var val = data.join('|');
    
                //search for the option(s) selected
                column
                  .search(val ? val : '', true, false)
                  .draw();
              });
    
            column.data().unique().sort().each(function (d, j) {
              select.append('<option value="' + d + '">' + d + '</option>');
            });
            $('#select-' + title).select2({
              multiple: true,
              closeOnSelect: true,
              placeholder: 'Choose '+title,
              width: '300px',
            });
            // Put default value for some column and null for other filters in the table
            if (title = 'some column') {
              $('.select2').val('some_defualt_val').trigger('change');
            } else {
              $('.select2').val(null).trigger('change');
            }
          });
     ```
    
  • Vishakha-92Vishakha-92 Posts: 15Questions: 0Answers: 0

    I built a test case
    http://live.datatables.net/huyetana/1/edit

    Here the filter is applied for Company 1, but the number 125 is also showing highlighted because it belongs to company 2. What I want is the results should only work with filter.
    Expected result: 125 should not be highlighted, since the duplicate doesn't exist with filter

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951
    edited May 2022

    Thanks for the test case. The rowCallback runs before initComplete so all of the cells in the Number column are set with the background color. Then the table is filtered and rowCallback runs again. You need to reset the background color, to a default color, in rowCallback before setting it with the if statement. Like this:
    http://live.datatables.net/huyetana/2/edit

    Kevin

  • Vishakha-92Vishakha-92 Posts: 15Questions: 0Answers: 0

    Thanks for the explanation and your quick response!!

  • Vishakha-92Vishakha-92 Posts: 15Questions: 0Answers: 0

    Is it also possible to highlight only the current index and not the last matching one.

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    Sorry, I'm not sure what you mean by highlight only the current index. Please provide more details of what you are trying to do.

    Kevin

  • Vishakha-92Vishakha-92 Posts: 15Questions: 0Answers: 0

    In this example, can I only highlight the single rows of duplicate data instead of highlighting both duplicate values.
    Eg : only 124 and 126 should be highlighted once, their first appearance. Just one and third row

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951

    Try using the Javascript splice() method to remove the highlighted value from allData array. The if statement will also need to make sure the value is in the array before highlighting.

    Kevin

  • Vishakha-92Vishakha-92 Posts: 15Questions: 0Answers: 0
    edited June 2022

    Okay one more question I have, if there's an easy way of doing that in datatables.
    Can we highlight the duplicate rows in alternate colour.
    Two duplicate rows in alternate colour
    Eg : 124 & 124 : one colour (green)
    126 & 126 : other colour (yellow)
    128 & 128 : one colour (green)

  • kthorngrenkthorngren Posts: 21,336Questions: 26Answers: 4,951
    edited June 2022

    There are no Datatables limitations. In the rowCallback you are using standard Javascript and jQuery statements to perform the actions you want. Based on your solution requirements you will need to decide how you want to control which color is used to highlight. Could be based on the data value. You could randomize the colors. You could keep track of a static array of colors and use a counter to keep track of the next color to use.

    EDIT:mIf you want to try a technique in the above test case and have questions let us know.

    Kevin

Sign In or Register to comment.