Correct way of firing draw() in events init and order

Correct way of firing draw() in events init and order

martafernandezmartafernandez Posts: 5Questions: 2Answers: 0
edited November 2022 in Free community support

Link to test case: http://live.datatables.net/yevonevo/1/edit?html,js,output

Description of problem: I am playing around with several ways of adding an index column, and I have come up with 2 different use cases:
1. Adding a "ranking" column right after initialization and assign fixed indexes to rows that will be preserved when re-ordering the table.
2. Adding a pure index, counter column as described here: https://datatables.net/examples/api/counter_columns.html

For the first case, the link in the test case works, but I am wondering about some behaviours:

$('#example').on('init.dt', function() {
    console.log('init');
        let i = 1;
        $('#example').DataTable().cells(null, 0, { search: 'applied', order: 'applied' }).every(function (cell) {
            this.data(i++);
        });
        
       //$('#example').DataTable().column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
       //     cell.innerHTML = i+1;
      //     });
  });

  var table = $('#example').DataTable({
    pageLength: 5,
    order: [[1,'asc']]
  });
  1. The uncommented code works perfectly for the ranking use case (assigning a fixed index value to each row at initialization, consistent after re-ordering). In addition, the table can be also ordered by this column values. On the other hand, the commented piece, when used instead of the code right above, creates the ranking fine, it is preserved when re-ordering, but the table cannot be re-ordered by the ranking column, that does not work. Why is that?

  2. Secondly, it is not necessary to add .draw() after changing the values in the index column so they appeared at initialization. On the other hand, in the example in https://datatables.net/examples/api/counter_columns.html , it is necessary to have the .draw() function after changing the values for it to appear at initialization too. I am guessing it is because at initialization the ordering event is not caught since it is defined after table initialization, is that assumption correct?

Thank you very much, and any insight is highly appreciated :) I do not have a lot of experience with javascript so maybe the questions are obvious, so I really appreciate any help.

Edited by Kevin: Syntax highlighting. Details on how to highlight code using markdown can be found in this guide

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,139Questions: 26Answers: 4,734
    Answer ✓
    1. The cell.innerHTML = i+1; is using Javascript methods to set the HTML cell's value. Datatables doesn't know about this change so the Datatables data cache is not updated which means Datatables can't sort by this changed values. The this.data(i++); is using a Datatables API to update the data so both the Datatables data cache and the DOM are updated.

    Datatables has some APIs like cell().invalidate(), row().invalidate(), etc that can be used to update the Datatables cache after doing direct DOM updates.

        t.on('order.dt search.dt', function () {
            let i = 1;
     
            t.cells(null, 0, { search: 'applied', order: 'applied' }).every(function (cell) {
                this.data(i++);
            });
        }).draw();
    

    This executes after initialization. The draw() API is only executed once when this statement is first executed to create the event handler. The chained draw() is not executed after the event handler runs when the table is sorted or searched.

    Hope this makes sense.

    Kevin

  • martafernandezmartafernandez Posts: 5Questions: 2Answers: 0

    Thank you very much for the detailed answer, everything is clear now.

    Just one last question, I don't totally get your last sentence:
    The chained draw() is not executed after the event handler runs when the table is sorted or searched.

    What do you exactly mean here? Or in what context do you mean the draw() is not executed?
    What I understand is that after any order or search event the draw() will be executed. At initialization, since this event handler has not been created yet, it does not execute, so the draw() does not either.

  • allanallan Posts: 61,431Questions: 1Answers: 10,048 Site admin

    I think Kevin's point is that the order of execution there is:

    1. Event handler is added
    2. Draw event fires

    Then, that will cause the order and search events to both run, executing your anonymous function. At that point the t.cells(...) code runs. The draw() does not then execute again (which is good since you'd run into an infinite loop!).

    Allan

  • martafernandezmartafernandez Posts: 5Questions: 2Answers: 0

    Ok, thank you a lot for the quick reply, I get the point of the answer now, I was trying to understand it focused on a different perspective because I didn't formulate my reasoning in a correct way.

Sign In or Register to comment.