orderData: Sort indicators on column ordered by another column don't update?

orderData: Sort indicators on column ordered by another column don't update?

RStewartRStewart Posts: 7Questions: 3Answers: 0

When using orderData to sort one column by a different column, the sort icons don't update correctly.

In the test case below, we're sorting column[1] based on column [2].

Test case:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>DataTables orderData Test</title>
        <script src="./jquery-3.7.1.min.js"></script>
        <script src="./datatables/2.0.7/datatables.min.js"></script>
        <link rel="stylesheet" type="text/css" href="./datatables/2.0.7/datatables.min.css" />
        <script type="text/javascript">
            $(document).ready(function() {
                $('#t1').DataTable({
                    columnDefs : [
                        { targets : 1, orderData : 2 }
                        , { targets : 2, visible : false }
                    ],
                    order : [ [ 1, "desc" ] ]
                });
            });
        </script>
    </head>
    <body>
        <table id="t1">
            <thead>
                <tr><th>Name</th><th>Date</th><th>Date-Sort</th></tr>
            </thead>
            <tbody>
                <tr><td>This is a name</td><td>20-Apr-2024</td><td>20240520</td></tr>
                <tr><td>Another name</td><td>25-May-2023</td><td>20230521</td></tr>
                <tr><td>Yet another name</td><td>28-Sep-2023</td><td>20230928</td></tr>
            </tbody>
        </table>
    </body>
</html>

The sort-direction indicators on column [1], labeled "Date", do not update, although clicking on that column heading does cause the table to be sorted as expected (i.e., based on content of column [2]). If we make column [2] visible, the sort indicators on column [2] change when we click on the heading for column [1].

We would expect the sort indicators on column [1] to change when we click on the heading for column [1].

Is this a known bug or are we using orderData incorrectly?

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Answer ✓

    There was a question along these lines earlier in the month - have a look at this thread where I show a workaround.

    I think there is an argument for both having that as the expected action, but also for the current behaviour. I don't think it is a bug, but the assumption I've made in how it currently works doesn't work for your scenario. I should maybe change that or perhaps provide a feature flag to change the behaviour.

    Allan

  • RStewartRStewart Posts: 7Questions: 3Answers: 0

    Thanks much, Allan. I'm not sure how I missed the earlier thread related to this. I will go that direction for now.

  • RStewartRStewart Posts: 7Questions: 3Answers: 0

    @allan With the update to 2.1.0, the approach used in the thread linked above and in the example linked from there no longer works if the column used as the basis for sorting is not visible (e.g., column 0 is sorted by column 1 and column 1 is not visible). From testing and debugging the classes related to ordering are not added to the not-visible column and thus don't get picked up and applied to the visible column.

    Do you have a recommendation for how to make this work?

  • ZowiezoZowiezo Posts: 1Questions: 0Answers: 0

    Hi RStewart,
    I'm encountering the same problem and I've solved it by changing the drawCallback as follows:

    drawCallback: function () {
        var api = this.api();
    
        // The array used to store the ordering into
        var order = [];
               
        // Get the current ordering of the table using the column names
        // instead of column indices
        api.order().map((obj) => {
            // The column and the direction in which they are ordered
            col_idx = obj[0];
            col_dir = obj[1];
            
            // The column name
            col_name = api.settings()[0].aoColumns[col_idx].name;
            
            // Inserting it into the order array
            order[col_name] = col_dir;
        });
    
        // All of the columns that use an invislbe column for sorting
        ["link", "book_start", "book_end"].forEach((column_name) => {
            // Check if this column is used for sorting
            if (column_name in order && order[column_name] !== "") {
                // Add the class needed to show the user that this 
                // column is actually being used for sorting
                api.column(column_name + ":name").header().classList.add(
                    order[column_name] === "asc" ? "dt-ordering-asc" : "dt-ordering-desc"
                );
            }
        });
    }
    

    It seems to work for me, so perhaps it can help you too! I'm using column names, since my tables are filled in dynamically. If you are using indices instead, you'll need to edit the function slightly

Sign In or Register to comment.