Sujit Baniya
Sujit Baniya

Reputation: 13

DataTables - Next/Previous pagination links to show next/previous full group of page numbers

In DataTables, is there any configuration or tweaks so that when I click on next, the complete next pages would appear?

For example, in current implementation, on clicking next button, the page shifts to only one, i.e.

first 1 2 3 4 ... next is shifted to first ...,2,3,4,5,... next

But I need the implementation:

first 1,2,3,4,... next. When clicked to next: first ...,5,6,7,8,... next.

How can I make it possible?

Upvotes: 1

Views: 1468

Answers (1)

Marcos Dimitrio
Marcos Dimitrio

Reputation: 6852

It's possible if you write a plugin.

I have modified the now deprecate Ellipses plugin to include an option for grouping the pagination numbers. This was tested with DataTables 1.10.7 and 1.9.4.

In your JavaScript, when you instantiate DataTables, use the pagingNumbersGrouping option to get the behavior you're after. I have made it default to false, so anyone can replace the original plugin with this one without breaking any current implementation.

$('#myTable').dataTable({
    "pagingType": "ellipses",         // use "sPaginationType" for DataTables v1.9 and earlier
    "showPages": 4,                   // default is 5
    "pagingNumbersGrouping": true,    // default is false
    "pagingExtraNumberForNext": true  // default is false, affects pagingNumbersGrouping behavior:
                                      //   when false: previous 1 2 3 4 ... next, (click next)
                                      //               previous ... 5 6 7 8 ... next
                                      //   when true: previous 1 2 3 4 5 ... next, (click "5" or next)
                                      //              previous ... 5 6 7 8 9 ... next
});

ellipses.js

$.extend($.fn.dataTableExt.oStdClasses, {
    'sPageEllipsis': 'paginate_ellipsis',
    'sPageNumber': 'paginate_number',
    'sPageNumbers': 'paginate_numbers',
    'sPageFirst': "first",           // These are 
    'sPagePrevious': "previous",     // necessary for
    'sPageNext': "next",             // newer versions
    'sPageLast': "last"              // of DataTables (>= 1.10)
});

$.fn.dataTableExt.oPagination.ellipses = {
    'oDefaults': {
        'showPages': 5,
        'pagingNumbersGrouping': false,
        'pagingExtraNumberForNext': false
    },
    'fnClickHandler': function (e) {
        var fnCallbackDraw = e.data.fnCallbackDraw,
            oSettings = e.data.oSettings,
            sPage = e.data.sPage;

        if ($(this).is('[disabled]')) {
            return false;
        }

        oSettings.oApi._fnPageChange(oSettings, sPage);
        fnCallbackDraw(oSettings);

        return true;
    },
    // fnInit is called once for each instance of pager
    'fnInit': function (oSettings, nPager, fnCallbackDraw) {
        var oClasses = oSettings.oClasses,
            oLang = oSettings.oLanguage.oPaginate,
            that = this;

        var showPages = oSettings.oInit.showPages || this.oDefaults.showPages,
            showPagesHalf = Math.floor(showPages / 2),
            pagingNumbersGrouping = oSettings.oInit.pagingNumbersGrouping || this.oDefaults.pagingNumbersGrouping,
            pagingExtraNumberForNext = oSettings.oInit.pagingExtraNumberForNext || this.oDefaults.pagingExtraNumberForNext;

        $.extend(oSettings, {
            _showPages: showPages,
            _showPagesHalf: showPagesHalf,
            _pagingNumbersGrouping: pagingNumbersGrouping,
            _pagingExtraNumberForNext: pagingExtraNumberForNext
        });

        var oFirst = $('<a class="' + oClasses.sPageButton + ' ' + oClasses.sPageFirst + '">' + oLang.sFirst + '</a>'),
            oPrevious = $('<a class="' + oClasses.sPageButton + ' ' + oClasses.sPagePrevious + '">' + oLang.sPrevious + '</a>'),
            oNumbers = $('<span class="' + oClasses.sPageNumbers + '"></span>'),
            oNext = $('<a class="' + oClasses.sPageButton + ' ' + oClasses.sPageNext + '">' + oLang.sNext + '</a>'),
            oLast = $('<a class="' + oClasses.sPageButton + ' ' + oClasses.sPageLast + '">' + oLang.sLast + '</a>');

        oFirst.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': 'first' }, that.fnClickHandler);
        oPrevious.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': 'previous' }, that.fnClickHandler);
        oNext.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': 'next' }, that.fnClickHandler);
        oLast.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': 'last' }, that.fnClickHandler);

        // Draw
        $(nPager).append(oFirst, oPrevious, oNumbers, oNext, oLast);
    },
    // fnUpdate is only called once while table is rendered
    'fnUpdate': function (oSettings, fnCallbackDraw) {
        var oClasses = oSettings.oClasses,
            that = this;

        var tableWrapper = oSettings.nTableWrapper;

        // Update stateful properties
        this.fnUpdateState(oSettings);

        if (oSettings._iCurrentPage === 1) {
            $('.' + oClasses.sPageFirst, tableWrapper).attr('disabled', true);
            $('.' + oClasses.sPagePrevious, tableWrapper).attr('disabled', true);
        } else {
            $('.' + oClasses.sPageFirst, tableWrapper).removeAttr('disabled');
            $('.' + oClasses.sPagePrevious, tableWrapper).removeAttr('disabled');
        }

        if (oSettings._iTotalPages === 0 || oSettings._iCurrentPage === oSettings._iTotalPages) {
            $('.' + oClasses.sPageNext, tableWrapper).attr('disabled', true);
            $('.' + oClasses.sPageLast, tableWrapper).attr('disabled', true);
        } else {
            $('.' + oClasses.sPageNext, tableWrapper).removeAttr('disabled');
            $('.' + oClasses.sPageLast, tableWrapper).removeAttr('disabled');
        }

        var i, oNumber, oNumbers = $('.' + oClasses.sPageNumbers, tableWrapper);

        // Erase
        oNumbers.html('');

        for (i = oSettings._iFirstPage; i <= oSettings._iLastPage; i++) {
            oNumber = $('<a class="' + oClasses.sPageButton + ' ' + oClasses.sPageNumber + '">' + oSettings.fnFormatNumber(i) + '</a>');

            if (oSettings._iCurrentPage === i) {
                oNumber.attr('active', true).attr('disabled', true);
            } else {
                oNumber.click({ 'fnCallbackDraw': fnCallbackDraw, 'oSettings': oSettings, 'sPage': i - 1 }, that.fnClickHandler);
            }

            // Draw
            oNumbers.append(oNumber);
        }

        // Add ellipses
        if (1 < oSettings._iFirstPage) {
            oNumbers.prepend('<span class="' + oClasses.sPageEllipsis + '">...</span>');
        }

        if (oSettings._iLastPage < oSettings._iTotalPages) {
            oNumbers.append('<span class="' + oClasses.sPageEllipsis + '">...</span>');
        }
    },
    // fnUpdateState used to be part of fnUpdate
    // The reason for moving is so we can access current state info before fnUpdate is called
    'fnUpdateState': function (oSettings) {
        var iCurrentPage = Math.ceil((oSettings._iDisplayStart + 1) / oSettings._iDisplayLength),
            iTotalPages = Math.ceil(oSettings.fnRecordsDisplay() / oSettings._iDisplayLength),
            iFirstPage,
            iLastPage;

        // Added, calculating pagingNumbersGrouping
        if (oSettings._pagingNumbersGrouping) {
            var pageSet = Math.ceil(iCurrentPage / oSettings._showPages);
            iLastPage = pageSet * oSettings._showPages;
            iFirstPage = iLastPage - (oSettings._showPages - 1);
            if (oSettings._pagingExtraNumberForNext) {
                iLastPage++;
            }
        } else {
            iFirstPage = iCurrentPage - oSettings._showPagesHalf;
            iLastPage = iCurrentPage + oSettings._showPagesHalf;
        }

        if (iTotalPages < oSettings._showPages) {
            iFirstPage = 1;
            iLastPage = iTotalPages;
        } else if (iFirstPage < 1) {
            iFirstPage = 1;
            iLastPage = oSettings._showPages;
        } else if (iLastPage > iTotalPages) {
            if (!oSettings._pagingNumbersGrouping) {
                iFirstPage = (iTotalPages - oSettings._showPages) + 1;
            }
            iLastPage = iTotalPages;
        }

        $.extend(oSettings, {
            _iCurrentPage: iCurrentPage,
            _iTotalPages: iTotalPages,
            _iFirstPage: iFirstPage,
            _iLastPage: iLastPage
        });
    }
};

Upvotes: 1

Related Questions