Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move a row up or down in a DataTable?

I am using the JavaScript library DataTables to display data.

I want to be able to reorder the rows. I saw there was an extension called RowReorder but it seems broken as even the examples found online don't reorder rows (at least in latest version of Chrome as of this writing). And even if it worked, I don't like this solution because it is not clear that you can reorder the rows.

So I would like to implement something like the following image:

DataTable reorder

I found several links online asking for that but it seems nobody could make it work properly.

My data source is a simple array. No ajax yet. I want to start simple.

Is it something you've done before? Any direction on how to start building that feature?

like image 987
Maxime Avatar asked Mar 10 '23 09:03

Maxime


1 Answers

Thank you to David Konrad for his guidance from his answer on another question on how to add a row in the middle of a table.

The first thing I did is start by creating an Action column in my table and dynamically add the Up or Down options.

{
    name: 'action',
    data: null,
    title: 'Action',
    searchable: false,
    sortable: false,
    render: function (data, type, full, meta) {
        if (type === 'display') {
            var $span = $('<span></span>');

            if (meta.row > 0) {
                $('<a class="dtMoveUp">Up</a>').appendTo($span);
            }

            $('<a class="dtMoveDown">Down</a>').appendTo($span);

            return $span.html();
        }
        return data;
    }
}

Then, I added code in the drawCallback to remove the Down arrow of the last row and bind the click event to moveUp and moveDown functions:

'drawCallback': function (settings) {
    $('#ArgumentsTable tr:last .dtMoveDown').remove();

    // Remove previous binding before adding it
    $('.dtMoveUp').unbind('click');
    $('.dtMoveDown').unbind('click');

    // Bind click to function
    $('.dtMoveUp').click(moveUp);
    $('.dtMoveDown').click(moveDown);
}

Then I coded the move up/down functions. It is important to note that my data has a order property that I use to change the order. This order is displayed as the first column and makes it the default sort column:

// Move the row up
function moveUp() {
    var tr = $(this).parents('tr');
    moveRow(tr, 'up');
}

// Move the row down
function moveDown() {
    var tr = $(this).parents('tr');
    moveRow(tr, 'down');
}

// Move up or down (depending...)
function moveRow(row, direction) {
    var index = table.row(row).index();

    var order = -1;
    if (direction === 'down') {
      order = 1;
    }

    var data1 = table.row(index).data();
    data1.order += order;

    var data2 = table.row(index + order).data();
    data2.order += -order;

    table.row(index).data(data2);
    table.row(index + order).data(data1);

    table.page(0).draw(false);
}

Note: It is important to understand that when you ask DataTable to draw() your table again, it will use your data to sort the results according to the parameters set in the DataTable definition. This is why I chose, for this example, to set the order as the first column (default sort) and alter my data objects directly (instead of playing with internal information from DataTable). That makes things a lot easier.

Note 2: It is really important that your data is received by the DataTable already sorted by order. Otherwise, this solution won't work as is.

You can check a full working example here:

https://jsfiddle.net/kxfx489y/4/

like image 111
Maxime Avatar answered Mar 13 '23 02:03

Maxime