Custom Paging Controls

Custom Paging Controls

jneilliiijneilliii Posts: 15Questions: 0Answers: 0
edited February 2011 in General
I am currently using version 1.6 of the DataTables library, and love it. One thing I was wondering though, is it possible to have custom paging. Currently, my implementation is using a jquery theme and the controls do show up and function, but only show 5 possible pages via direct button click and the first/next/previous/last buttons. Is it possible to switch the numbered buttons to a pull-down menu that shows all the pages available?

Replies

  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    It;s certainly possible, but there isn't a plug-in which will specifically do that yet. There is documentation on how to write such a plug-in: http://datatables.net/development/pagination - and also a number of plug-ins which have already been written: http://datatables.net/plug-ins/pagination . If you create the one you describe, it would be great if you could share the code with us so I can put it up on the plug-ins page :-)

    Allan
  • jneilliiijneilliii Posts: 15Questions: 0Answers: 0
    edited February 2011
    Thanks Allan, after posting I did see the section you are describing. I will see what I can come up with and definitely post the code once I have it working to my satisfaction.
  • jneilliiijneilliii Posts: 15Questions: 0Answers: 0
    edited February 2011
    Allan, please see if this works for you, it appears to be working for me as I need. I hope this may help others using DataTables that wants this listbox functionality. It could be easily adopted to include other controls, but I didn't find them necessary (ie First, Previous, etc.) as you can just select from the list where you want to go directly. I started with your text input example and basically removed the extra controls, and replaced the text input with a select list.

    [code]$.fn.dataTableExt.oPagination.listbox = {
    /*
    * Function: oPagination.listbox.fnInit
    * Purpose: Initalise dom elements required for pagination with listbox input
    * Returns: -
    * Inputs: object:oSettings - dataTables settings object
    * node:nPaging - the DIV which contains this pagination control
    * function:fnCallbackDraw - draw function which must be called on update
    */
    "fnInit": function (oSettings, nPaging, fnCallbackDraw) {
    var nInput = document.createElement('select');
    var nPage = document.createElement('span');
    var nOf = document.createElement('span');
    nOf.className = "paginate_of";
    nPage.className = "paginate_page";
    if (oSettings.sTableId !== '') {
    nPaging.setAttribute('id', oSettings.sTableId + '_paginate');
    }
    nInput.style.display = "inline";
    nPage.innerHTML = "Page ";
    nPaging.appendChild(nPage);
    nPaging.appendChild(nInput);
    nPaging.appendChild(nOf);
    $(nInput).change(function (e) { // Set DataTables page property and redraw the grid on listbox change event.
    window.scroll(0,0); //scroll to top of page
    if (this.value === "" || this.value.match(/[^0-9]/)) { /* Nothing entered or non-numeric character */
    return;
    }
    var iNewStart = oSettings._iDisplayLength * (this.value - 1);
    if (iNewStart > oSettings.fnRecordsDisplay()) { /* Display overrun */
    oSettings._iDisplayStart = (Math.ceil((oSettings.fnRecordsDisplay() - 1) / oSettings._iDisplayLength) - 1) * oSettings._iDisplayLength;
    fnCallbackDraw(oSettings);
    return;
    }
    oSettings._iDisplayStart = iNewStart;
    fnCallbackDraw(oSettings);
    }); /* Take the brutal approach to cancelling text selection */
    $('span', nPaging).bind('mousedown', function () {
    return false;
    });
    $('span', nPaging).bind('selectstart', function () {
    return false;
    });
    },
    /*
    * Function: oPagination.listbox.fnUpdate
    * Purpose: Update the listbox element
    * Returns: -
    * Inputs: object:oSettings - dataTables settings object
    * function:fnCallbackDraw - draw function which must be called on update
    */
    "fnUpdate": function (oSettings, fnCallbackDraw) {
    if (!oSettings.aanFeatures.p) {
    return;
    }
    var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
    var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1; /* Loop over each instance of the pager */
    var an = oSettings.aanFeatures.p;
    for (var i = 0, iLen = an.length; i < iLen; i++) {
    var spans = an[i].getElementsByTagName('span');
    var inputs = an[i].getElementsByTagName('select');
    var elSel = inputs[0];
    if (elSel.options.length === 0) { // populate listbox with options if it doesn't already have them.
    for (var j = 0; j < iPages; j++) {
    var oOption = document.createElement('option');
    oOption.text = j + 1;
    oOption.value = j + 1;
    try {
    elSel.add(oOption, null); // standards compliant; doesn't work in IE
    } catch (ex) {
    elSel.add(oOption); // IE only
    }
    }
    }
    spans[1].innerHTML = " of " + iPages;
    elSel.value = iCurrentPage;
    }
    }
    };
    [/code]
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Looks excellent! Thanks very much for sharing it with us :-). I've added it to the pagination plug-ins here: http://datatables.net/plug-ins/pagination#listbox . If you'd like the credit altered at all (name / link) please just let me know :-)

    Regards,
    Allan
  • jneilliiijneilliii Posts: 15Questions: 0Answers: 0
    Allan, I just noticed a problem with my listbox paging navigation. If you load the data and then filter the listbox doesn't change the page numbering because I don't clear the listbox. Is there a flag for filtering in oSettings that I could use to determine if I need to repopulate the listbox options?
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    No - the general rule is that there isn't really a rule for this :-). If there is a redraw, then you should assume that it's an entirely new state - and therefore repopulate the list each time. fnUpdate will be called on each redraw (including filtering). So I think you just need to add a clear out in there.

    Allan
  • jneilliiijneilliii Posts: 15Questions: 0Answers: 0
    Thanks, I had that before but didn't think it made sense to popuate the listbox every redraw...guess I was wrong. The modifed fnUpdate command is listed below. If you could, please make this change in the pagination plug-ins section as well.

    [code]
    "fnUpdate": function (oSettings, fnCallbackDraw) {
    if (!oSettings.aanFeatures.p) {
    return;
    }
    var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
    var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1; /* Loop over each instance of the pager */
    var an = oSettings.aanFeatures.p;
    for (var i = 0, iLen = an.length; i < iLen; i++) {
    var spans = an[i].getElementsByTagName('span');
    var inputs = an[i].getElementsByTagName('select');
    var elSel = inputs[0];
    elSel.options.length = 0; //clear the listbox contents
    for (var j = 0; j < iPages; j++) { //add the pages
    var oOption = document.createElement('option');
    oOption.text = j + 1;
    oOption.value = j + 1;
    try {
    elSel.add(oOption, null); // standards compliant; doesn't work in IE
    } catch (ex) {
    elSel.add(oOption); // IE only
    }
    }
    spans[1].innerHTML = " of " + iPages;
    elSel.value = iCurrentPage;
    }
    }

    [/code]
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Thanks for the update :-) - I've put it up on the site now.

    It would be possible to check what has changed and if it's really necessary to update the list box, however, it's such an inexpensive operation generally I don't think it's worth it here (although of course that might not always be true!).

    Regards,
    Allan
  • jneilliiijneilliii Posts: 15Questions: 0Answers: 0
    Another small update to avoid the overhead, just in case...I am now comparing the iPages value to the select list options length to determine if it's necessary to change the options.

    [code]
    "fnUpdate": function (oSettings, fnCallbackDraw) {
    if (!oSettings.aanFeatures.p) {
    return;
    }
    var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
    var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1; /* Loop over each instance of the pager */
    var an = oSettings.aanFeatures.p;
    for (var i = 0, iLen = an.length; i < iLen; i++) {
    var spans = an[i].getElementsByTagName('span');
    var inputs = an[i].getElementsByTagName('select');
    var elSel = inputs[0];
    if(elSel.options.length != iPages) {
    elSel.options.length = 0; //clear the listbox contents
    for (var j = 0; j < iPages; j++) { //add the pages
    var oOption = document.createElement('option');
    oOption.text = j + 1;
    oOption.value = j + 1;
    try {
    elSel.add(oOption, null); // standards compliant; doesn't work in IE
    } catch (ex) {
    elSel.add(oOption); // IE only
    }
    }
    spans[1].innerHTML = " of " + iPages;
    }
    elSel.value = iCurrentPage;
    }
    }
    [/code]
  • allanallan Posts: 63,516Questions: 1Answers: 10,472 Site admin
    Keep them coming :-). Updated the plug-in page with the latest code.

    Allan
This discussion has been closed.