Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Sort only the current page using Jquery Datatable

I have been using Jquery datatable for many projects and it's working perfectly for all scenarios.

For my current project I require sorting to be happened only for current page but by default datatable will sort whole data and redraw the entire table.

I was sure there will be some simple configuration for enable this feature but couldn't find any except these lines from their forum

var table = $('#example').DataTable();

// Sort by column 1 and then re-draw
table
    .order( [[ 1, 'asc' ]] )
    .draw( false ); 

I tried this but it doesn't seems to make any effect. any one has implemented this successfully before please share your code.

like image 986
ssilas777 Avatar asked Dec 12 '14 06:12

ssilas777


Video Answer


3 Answers

Before asking how to sort only current page we should answer following questions:

  • Why do we want to do such sorting?
  • Should we do it?
  • Does it have any sense?
  • What are the implications of such decision?

When we want to execute a query and display the result list we are dealing with:

  • searching criteria
  • sorting criteria
  • pagination

These three elements are strongly related and they clearly define what user sees on the screen.
We can have for example following description:

There is a list of actors. It is sorted by name and divided into pages (50 items per page). And we are on the third page.

When we have such rules then user has good orientation in this list. He sees Michael Caine at the top and Shon Connery on the bottom of the page. When he wants to find Robert Duvall he knows he should go few pages further. And when he wants to see these actors sorted by age he simply resorts the lists and returns to first page.

But what if we provide additional sorting only for current page? This would disturb cohesion of above system. How would it sound if we say to user:

You are now seeing third page of sorted-by-name list of actors resorted (page) by age.

What can this user gain by resorting only current page? Age hierarchy of actors with name starting with 'C'? At the top of the page there will be the oldest actor from this page. But user doesn't know if it the oldest actor in all the list. And if not then on which page should he look for older one? Such resorting is worthless and it overrides initial sorting (which had some value).

Such resorting can also lead user to serious confusion. He can loose his orientation about original sorting and page sorting.

Conclusions:

I don't see any sense in providing sorting for single page. I find it harmful. So you should use it only if you have strong arguments for it.

like image 178
rtruszk Avatar answered Nov 15 '22 09:11

rtruszk


Update 1

Although I agree with rtruszk, I still think a solution should be found/explored if 0) you have no choice or 1) your client is not willing to discuss UX changes.

Working Example: http://jsfiddle.net/ebRXw/63/

I was able to accomplish what you were after by filtering out the currently visible rows from the DataTable. I tried my best to find a solution within DataTables, and one may exist, but in the end I used jQuery and a hash table to identify and filter out the currently visible rows.

I'm sure this can be optimized further. Hopefully, it gets you moving in the right direction.

$(document).ready(function () {

    var table = $('#example').DataTable({
        "columnDefs": [{
            "targets": [0],
                "visible": false,
                "searchable": true
        }]
    });

    // Show page 0
    table.page(0).draw(false);
    // Sort by column 1 (Name)
    table.order([1, 'asc']).draw(false);

    $("#ReloadTable").click(function () {
        // Clear the current filter
        oTable = $('#example').dataTable();
        oTable.fnFilter('', 0);
        oTable.fnFilter('');

        // Reset all "visible" values in the first cell
        var table = $('#example').DataTable();
        table.rows().indexes().each(function (idx) {
            var d = table.row(idx).data();
            table.row(idx).data()[0] = 0;
            d.counter++;
            table.row(idx).data(d);
        });
    });

    $("#FilterCurrentPage").click(function () {
        // Create a hash of the index of currently visible rows
        var h = new Object();
        var x = $('.odd,.even').filter(function () {
            var idx = $(this)[0]._DT_RowIndex;
            h[idx] = idx;
            return this.style.display == ''
        });

        // update the first value based on the currently visible rows
        var table = $('#example').DataTable();
        table.rows().indexes().each(function (idx) {
            var d = table.row(idx).data();
            if (h.hasOwnProperty(idx)) {
                table.row(idx).data()[0] = 1;
            }
            d.counter++;
            table.row(idx).data(d);
        });

        // filter rows with a value of 1 in the first cell
        oTable = $('#example').dataTable();
        oTable.fnFilter(1, 0);
    });
});

Update 0

I still haven't found a workaround, but I'm convinced one exists. The code below will select and return the current visible rows in your datatable.

var x = $('.odd,.even').filter(function () {
    $(this).addClass('selected'); // Select the visible rows
    return this.style.display == '' 
});

From the DataTables maintainer:

Is there an easy way to tell datatables that I want to sort and redraw only current pagination?

In DataTables 1.9- no, there isn't a way of doing that, but in 1.10 you can use table.order( ... ).draw( false ); to preserve paging. 1.10 pre beta is available in git if you want to give it a bash :-)

Allan

via datatables: sort only current pagination of table

However, you might be able to get the current visible rows, sort them, and display them somehow. The below code provides the current visible rows after filtering.

var table = $('#example').DataTable();
table.$('tr', {"filter":"applied"});

See also:

  • jquery DataTables. How to get filtered (visible) rows
  • fnGetData of visible rows only
  • Retrieving row data after filtering JQuery Datatables
like image 37
JSuar Avatar answered Nov 15 '22 08:11

JSuar


The solution suggested by @JSuar is good but one thing I don't like about it is that, you have to click extra buttons every time you want to sort the table and also the pagination is disabled (which for me is not very natural). If it suits your use-case then go head! But if you don't want to click those extra buttons to reload the table every time, and if you want to keep the table as natural as possible we can do the following.

Algorithm

  • Disable Datatables inbuilt sort feature.
  • Get the rows on the current page and sort them on your own.
  • Redraw the table with the sorted rows.

Working js fiddle: https://jsfiddle.net/manikumarperla/rhsz2qnt/39/

End result (Sort only the current page)

Datatable with a feature to sort only the current page

By using your own sorting logic, you have full control over the table and you can literally do anything.

like image 32
Manikumar Perla Avatar answered Nov 15 '22 07:11

Manikumar Perla