Disabling Pagination Navigation When Returning Only One Page of Results

Disabling Pagination Navigation When Returning Only One Page of Results

dwadwa Posts: 5Questions: 0Answers: 0
edited April 2009 in General
Hello:

I am wondering if it is possible to currently disable pagination navigation elements if there is only one page of results returned.

Thanks very kindly in advance.

Replies

  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    Hi dwa,

    This isn't directly possible as DataTables doesn't support enabling and disabling features are run time. However, what you could do is make use of the fnDrawCallback() function to check to see if there is only one page, and if so hide the pagination controls.

    Give me a shout if you need a starting point with the code for this.

    Allan
  • swamyveeraswamyveera Posts: 4Questions: 0Answers: 0
    Hi Allan

    How should i go about it?
    I tried this

    oTable=$j('#tablesorter').dataTable( {
    "sPaginationType": "full_numbers",
    "bFilter": false,
    "bSearchable":false,
    "bInfo":false,
    "fnDrawCallback":function(){
    if($j("#tablesorter").find("tr:not(.ui-widget-header)").length<=5){
    /* What should go here */
    }
    }
    } );

    But am not sure how to proceed with the code, when i try to access oTable, i get an error saying oTable is not defined. How can i change the table settings in the call back?

    Thanks
    Vru
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    Hi Vru,

    Try something like this:

    [code]
    oTable=$j('#tablesorter').dataTable( {
    "sPaginationType": "full_numbers",
    "bFilter": false,
    "bSearchable":false,
    "bInfo":false,
    "fnDrawCallback":function(){
    if($j("#tablesorter").find("tr:not(.ui-widget-header)").length<=5){
    $('#tablesorter div.dataTables_paginate')[0].style.display = "none";
    } else {
    $('#tablesorter div.dataTables_paginate')[0].style.display = "block";
    }
    }
    } );
    [/code]

    It just takes the pagination element and toggles the display style as needed.

    I don't thing you need to actually use oTable inside the callback in this case, but if you are interested as to why not, have a look at this post: http://datatables.net/forums/comments.php?DiscussionID=200&page=1#Item_4

    Regards,
    Allan
  • archimedearchimede Posts: 6Questions: 0Answers: 0
    Hi Allan.

    First off, kudos for your great work: have yet to experiment with the server-side part of it, but I'm really pleased with what I can accomplish so far.

    As for the current thread:

    >> This isn't directly possible as DataTables doesn't support enabling and disabling features are run time

    I'm not really a JS or Ajax expert, so this is a bit confusing to me: your component is obviously aware of the current pagination state (eg. displaying page numbers) and I had the impression it's already capable of "dynamically" adjust the produced code accordingly (eg. class="paginate_active" vs class="paginate_button").

    So why isn't it possible to hide the whole div altogether when the total number of pages is 1? Another (related) thing I'd like to request is hiding the first/previous buttons when on page 1 and the next/last buttons when on last page.

    Thanks for considering.

    Cheers.

    Alessandro
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    Hi Alessandro,

    Thanks for your kind words - very much appreciated!

    What you are looking for certainly is possible, but it would require either a small modification to DataTables, or ideally a custom pagination plug-in ( http://datatables.net/development#pagination ).

    What I had meant by enabling and disabling features was that toggling a "whole" feature such as sorting, or filtering isn't supported by DataTables during runtime. Tweaking of features such as what you are looking for however most certainly is through the API that DataTables presents.

    Probably the easiest way to create a custom pagination function for what you want to do, is to take the core code from DataTables and modify it as needed, and then add it as a plug-in (there is currently one example plug-in: http://datatables.net/plug-ins#pagination ).

    Hope this helps,
    Allan
  • myqalanmyqalan Posts: 13Questions: 0Answers: 0
    edited January 2010
    I ran into this issue today, but mine is a little more complex. I wanted to be able to "hide" the pagination controls completely if only one page of information is displayed, whether that be at load, using the filter (search) box or after changing the number of records to display from the drop-down at the top of the table.

    Utilizing the information Allan offered above, I was able to make a small modification to the code that accomplishes this perfectly.

    [code]
    "fnDrawCallback":function(){
    if ( $('#writerHistory_paginate span span.paginate_button').size()) {
    $('#writerHistory_paginate')[0].style.display = "block";
    } else {
    $('#writerHistory_paginate')[0].style.display = "none";
    }
    }
    [/code]

    By looking to see if exists we can then toggle the display as necessary. This class is only used when more than one page will be displayed (ie. if you have two pages of records, the button for page two in the pagination controls would be this element and class).

    I hope this helps some of you.

    And thanks again Allan for an incredible product!!
  • allanallan Posts: 63,679Questions: 1Answers: 10,498 Site admin
    Hi myqalan,

    Nice piece of code that (and thanks for the kind words!). I've sure others will find it most useful, as it can be a very effective UI "trick".

    Regards,
    Allan
  • jcallasjcallas Posts: 6Questions: 0Answers: 0
    Hi myqalan,

    Nice code but it does not seem to work on the initial load. My guess is that the first time dnDrawCallback is raised the pagination buttons have not been added yet. As soon as I change the items per page amount of enter a search value the hide/show logic works.

    - Jason
  • jcallasjcallas Posts: 6Questions: 0Answers: 0
    Another issue with myqalan's code is using the Search feature. Seems that the fnDrawCallback event is raised BEFORE the pagination is updated (based on filtered values) so pagination does not reflect the proper number of buttons.

    - Jason
  • eeyore145eeyore145 Posts: 12Questions: 0Answers: 0
    I know this thread is a little old now and I'm sorry to resurrect it again, but has anyone come up with a method to accomplish this. I have tried various code in the fnDrawCallBack method and I seeing the same behavior as mentioned earlier - - it doesn't work on initial load. It appears the first time this event is raised the pagination div has not been rendered yet. The code I have tried does work when you click on the "1" or "2" page buttons, but I really need this to work on initial load.

    As an example, if I piece down the DOM step by step (I am using Full Numbers as my pagination):

    var spans = jQuery('span.paginate_button').not('.first').not('.last').not('.previous').not('.next');

    On initial load, even if there is a page 2 the size() of spans is 0. After I click on page 2 the size() is 1, also if click back on page 1, the size() is 1, etc. However I am unable to hide the pagination div on initial load.

    Any ideas?

    Thanks
  • myqalanmyqalan Posts: 13Questions: 0Answers: 0
    I just verified that the hide/show of the pagination does work once the table is loaded and the dataTables function is fired.

    Unfortunately the table that it is implemented in is in a password protected part of my employers site, so I can't share it.

    The following code is taken directly from the page that has the working table.

    [code]$('#student').dataTable( {
    "sPaginationType": "full_numbers",
    "bAutoWidth": false,
    "fnDrawCallback":function(){
    if (( $('#student_paginate span span.paginate_button').size()) && ($('br.spacer').size())) {
    $('#student_paginate')[0].style.display = "block";
    } else {
    if ( $('#student_paginate span span.paginate_button').size()) {
    $('#student_paginate')[0].style.display = "block";
    $('#student_wrapper').append('
  • eeyore145eeyore145 Posts: 12Questions: 0Answers: 0
    edited June 2010
    Myqalan:

    Unfortunately I am not seeing the same behavior as you. Using this exact code the pagination div is being hidden even when it shouldn't be. Looking at FireBug, there are various paginate_button classes so the size() call in this case would return 4, so I'm not sure if this code is just checking for the existence of the class, but the "next" and "previous" buttons for example (when using full_number style) also have the style of paginate_button.

    I am using the follow code to mimic yours:

    [code]
    oTable = jQuery('#commentListing').dataTable({
    "bFilter": false,
    "bSort": false,
    "bStateSave": true,
    "bAutoWidth": false,
    "bInfo": false,
    "bLengthChange": false,
    "iDisplayLength": 10,
    "sPaginationType": "full_numbers",
    "fnDrawCallback": function() {
    if (jQuery('#commentListing_paginate span span.paginate_button').size()) {
    jQuery('#commentListing_paginate')[0].style.display = "block";
    }
    else {
    jQuery('#commentListing_paginate')[0].style.display = "none";
    }
    },
    "aoColumns": ......
    [/code]

    And I am not seeing the behavior you are. Not sure if it matters but I am populating my DataTable via an AJAX source using fnReloadAjax

    [code]
    jQuery.fn.dataTableExt.oApi.fnReloadAjax = function(oSettings, loc, paramset) {.......
    [/code]

    What version are you using?

    But from what I can see, its not working for me.

    Thanks
  • myqalanmyqalan Posts: 13Questions: 0Answers: 0
    Eeyore,

    I'm using 1.5.4.

    I have uploaded a video of the code in action at...http://www.youtube.com/watch?v=7ybwnGjwdZQ

    The video shows two things:

    First, a data set with 70 entries is displayed with pagination visible. I then filter the results until less than 10 items are displayed.

    Second, I chose a data set with only 8 entries. When the table loads, you can see that the pagination controls are hidden on load.
  • eeyore145eeyore145 Posts: 12Questions: 0Answers: 0
    edited June 2010
    I never said you were lying about your specific implementation but I am not getting the same results you are.

    I am using DataTables version 1.61 and JQUERY 1.41. I have a datatable defined how I showed above, and on document load via, document.Ready() I define the DataTable and then populate it via an AJAX Call, through fnReloadAjax.

    My investigation so far has shown me that under this setup the paging buttons (the sub spans after the first and next buttons ) are not registered until after the FnDrawCallBack is invoked on initial load and setup.

    This is very easily reproducible. How are you populating your datatable?
  • myqalanmyqalan Posts: 13Questions: 0Answers: 0
    My table is populated using ColdFusion and an Oracle database.

    I would guess that your problem lies with the fact that you are drawing the table, then populating it via AJAX, as you have previously mentioned. Mine is actually populated as the page loads, so the table has all of its data prior to the dataTables call being fired.

    I don't have much experience using AJAX calls, but I'd imagine there is some way to tell the Data Tables function to redraw the table after the initial AJAX load.

    Sorry for the confusion.
  • akreiderakreider Posts: 33Questions: 0Answers: 0
    I was very happy to find this post. It worked great for me!

    It might almost make sense to make this default behavior. My guess is that most people are using this to display contents - and aren't doing as much editing (and thus if the table starts off with less than a page set of rows, they aren't going to add items - and won't need to use pagination).

    Or you could have two default behaviors - one for edit mode, and one for display mode. And then create a "displaymode" variable for the datatable initialization.
  • MrRooMrRoo Posts: 10Questions: 0Answers: 0
    edited June 2010
    I did this same task slightly differently, try:

    [code]
    "fnDrawCallback": function() {
    if (Math.ceil((oTable.fnSettings().fnRecordsDisplay()) / oTable.fnSettings()._iDisplayLength) > 1) {
    $('#DIVID_paginate')[0].style.display = "block";
    } else {
    $('#DIVID_paginate')[0].style.display = "none";
    }
    }
    [/code]
  • jd198100jd198100 Posts: 4Questions: 0Answers: 0
    Hi Allan,

    Great tool - I am using the most current version and am struggling to get the examples here to work. Has anything changed in the most recent version that the examples here wouldn't work? I would like to hide pagination controls always if there is only 1 page of records.
  • jd198100jd198100 Posts: 4Questions: 0Answers: 0
    Nevermind, I used the solution here provided by loige:

    http://datatables.net/forums/comments.php?DiscussionID=2138
  • MrRooMrRoo Posts: 10Questions: 0Answers: 0
    I am still using 1.7.1, however I would imagine any changes by Allan would not affect this "fix" as the code hides the pagination controls generated by DataTables.

    I would check the ID of the DIV that is created by DataTables (it is not #DIVID_paginate), if you are using the example code it would be: #example_paginate.

    MrRoo.
  • jd198100jd198100 Posts: 4Questions: 0Answers: 0
    I took this one step further with loige's solution:

    [code]

    "fnDrawCallback": function() {
    if (Math.ceil((this.fnSettings().fnRecordsDisplay()) / this.fnSettings()._iDisplayLength) > 1) {
    $('.dataTables_paginate').css("display", "block");
    $('.dataTables_length').css("display", "block");
    $('.dataTables_filter').css("display", "block");
    } else {
    $('.dataTables_paginate').css("display", "none");
    $('.dataTables_length').css("display", "none");
    $('.dataTables_filter').css("display", "none");
    }
    }

    [/code]
  • lusilusi Posts: 2Questions: 0Answers: 0
    Hi everyone .

    I am using jquery 1.4.1 and jquery datatable, if paginate_active is 1 I want that first and previous spans style set (cursor: text) otherwise (cursor: pointer)
    and when paginate_active span is the last page next and last spans style set (cursor: text).
    Is this possible ?

    Thanks
  • deckarddeckard Posts: 6Questions: 0Answers: 0
    jd198100's solution works for me, except that I have two datatables on the page and the CSS is affecting both of them. Can anyone suggest how to limit the CSS so that it is applied only to this datatable?

    Thanks!
  • deckarddeckard Posts: 6Questions: 0Answers: 0
    edited June 2011
    I figured out how to only apply the CSS to my specific datatable:
    [code]
    "fnDrawCallback": function() {
    if (Math.ceil((this.fnSettings().fnRecordsDisplay()) / this.fnSettings()._iDisplayLength) > 1) {
    $('#nonEmployees_paginate.dataTables_paginate').css("display", "block");
    $('#nonEmployees_filter.dataTables_filter').css("display", "block");
    } else {
    $('#nonEmployees_paginate.dataTables_paginate').css("display", "none");
    $('#nonEmployees_filter.dataTables_filter').css("display", "none");
    }
    if (this.fnSettings().fnRecordsDisplay() > 10) {
    $('#nonEmployees_length.dataTables_length').css("display", "block");
    } else {
    $('#nonEmployees_length.dataTables_length').css("display", "none");
    }
    }
    [/code]
    I also used a separate test for the length display, otherwise it disappears if you set it to a value that allows all the rows to be displayed.
  • JosephJoseph Posts: 9Questions: 0Answers: 0
    edited January 2012
    Hi !
    I'm using datatables v1.8.2, and this is the solution i'm using :

    [code]
    "fnDrawCallback": function(){
    if(this.fnSettings().fnRecordsDisplay()<=$("#tab_resultat_length option:selected" ).val()
    || $("#my_tab_length option:selected" ).val()==-1)
    $('#tab_resultat_paginate').hide();
    else $('#my_tab_paginate').show();
    }
    [/code]
  • tomas_eklundtomas_eklund Posts: 14Questions: 1Answers: 0
    edited March 2012
    I do not quite understand the logic behind some of the snippets of code posted here. For example, why use if(Math.ceil(x/y)>1) instead of if(x>y)? Not only does it make the code bulkier and harder to understand - it's also less efficient (not that it would make any real world difference, but still). A lot of the posted code also relies on hard coding IDs instead of self-referencing the table in question, which makes the code "unportable" (one have to adjust it when reusing it on another table). Also I don't understand why one, generally, would want to disable filtering just because the data fits on a single page.

    However, I do understand that we all have different needs, and the code examples provided by fellow posters have helped me a lot along the way when writing my own version, so I'd like to extend my gratitudes and give something back by posting what I've come up with. It's not perfect but maybe someone can take it and perfect it. Preferably I think the functionality should be integrated into the DataTables core since so many users want it. Hint hint, Allan...! ;-)

    Here is what I wanted:
    1. When the displayed content fits on a single page, hide pagination controls
    2. When the displayed content fits on a single page no matter which page length is selected, hide the page length control (that is if the number of rows to display is less than or equal to the minimum entry in the length control/aLengthMenu).
    3. The code should work even with several datatables on one html-page, also when using the same call to initiate them all, like:

    [code]
    // several tables with class datatable exist on the same page
    $('.datatable').dataTable(options);
    [/code]

    I've made a few assumptions, like for example that aLengthMenu[0][0] contains the lowest number. If one reverses the order of the aLengthMenu array (putting the highest number on top in the ) or if a single dimension array is used, adjustments are needed. Comments and corrections are appreciated.

    By finding the DataTables wrapper and using it as the context parameter to the jQuery selector calls, we can make sure to not accidentally hide the controls in other DataTables on the page.

    [code]
    fnDrawCallback: function(){
    var wrapper = this.parent();
    var rowsPerPage = this.fnSettings()._iDisplayLength;
    var rowsToShow = this.fnSettings().fnRecordsDisplay();
    var minRowsPerPage = this.fnSettings().aLengthMenu[0][0];
    if ( rowsToShow <= rowsPerPage || rowsPerPage == -1 ) {
    $('.dataTables_paginate', wrapper).css('visibility', 'hidden');
    }
    else {
    $('.dataTables_paginate', wrapper).css('visibility', 'visible');
    }
    if ( rowsToShow <= minRowsPerPage ) {
    $('.dataTables_length', wrapper).css('visibility', 'hidden');
    }
    else {
    $('.dataTables_length', wrapper).css('visibility', 'visible');
    }
    }
    [/code]

    EDIT: Fixed a bug in the code where a hidden length control would not reappear when adding rows to the table. Also changed .hide() to .css('visibility', 'hidden') because I wanted the hidden controls to still take up space in the header/footer so that the appearance of the header/footer would not otherwise change. When using .hide() the header/footer became slimmer and I didn't like that.
  • tomas_eklundtomas_eklund Posts: 14Questions: 1Answers: 0
    Alright... It seems like I didn't research this topic hard enough before posting. Just in case someone else stumbles upon this thread: Before you try out any of the code posted above, I'd like to point out that Allan has already shown us how to do this the proper way:

    http://datatables.net/blog/Creating_feature_plug-ins
This discussion has been closed.