sInfo reporting wrong _START_ value when iDisplayLength is changed...

sInfo reporting wrong _START_ value when iDisplayLength is changed...

lililili Posts: 9Questions: 0Answers: 0
edited January 2013 in General
Hi Allan / any other life saver out there :)

If I go to this example:
http://www.datatables.net/release-datatables/examples/basic_init/alt_pagination.html
the default is to show 10 entries per page. If I go to page 6 on the page buttons, I see the expected info:
Showing 51 to 57 of 57 entries.

However, if I change the _iDisplayLength from 10 to 50 while still on page 6, then:
1) the table is reloaded (expected)
2) the pagination controls shows that I'm now on page 2 (expected since record 51 is > new page length of 50)
3) the info shows: Showing 8 to 57 of 57 entries. (NOT expected)

Since I'm on page 2 with page size of "50" I'd have expected the info in #3 to show:
Showing 51 to 57 of 57 entries

Note that when I click the page "1" button, it correctly shows me the info:
Showing 1 to 50 of 57 entries.

I've been browsing the forums and seen some posts back in 2010 related to this, and other forum answers saying to look at using other plugins but this to me seems to be a bug.

Using the datatables.net example above, how is this corrected?

Thanks in advance for any time / help :)
lili

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    > _iDisplayLength

    That's a private variable. Anything in fnSettings should be treated as read-only unless you know exactly what the DataTables internals are doing for it (and even then it is liable to change between versions).

    Use the fnPageChange API method to jump to a different page.

    Allan
  • lililili Posts: 9Questions: 0Answers: 0
    edited January 2013
    Hi Allan,

    I was just using "iDisplayLength" in my text so you'd know what I was talking about. I'm not touching the variable at all. I was purely trying to say if the user uses the page size drop-down box on the web page to change the value (as per my example from 10 to 50) then I believe that there's a bug with the values reflected in the updated "info" text.

    I pointed to an example here on the datatables.net site so you'd know I'm not hacking anything but using datatables untouched :)

    When datatables changes to page 2 (where it's set to show 50 entries per page) with the default behaviour, I don't think I should have to manually alter something to ensure it displays the correct info?

    THanks for the super-quick response!
    lili
  • lililili Posts: 9Questions: 0Answers: 0
    (i.e. I don't think I should have to call the fnPageChange since the datatable is already calculating the new page "number" and at the same time should be recalculating the value of _START_ to display in sInfo)
  • lililili Posts: 9Questions: 0Answers: 0
    Also to make sure I wasn't unclear in the problem description, when viewing record #51 (with page size "10") and I do the following steps:

    Change page size from "10" (while on page #6) to page size "50" (using the drop down box), it will:
    1) show page #2 => the info says "Showing 8 to 57 of 57 entries"
    then if I say to
    2) show page #1=> the info says "Showing 1 to 50 of 57 entries"
    then I say to
    3) show page #2 => the info says "Showing 51 to 57 of 57 entries"

    Note how 1) and 3) above should show the exact same output info but they don't.

    (This problem seems to exist on all web sites using datatables with the full_numbers paging option.)
  • lililili Posts: 9Questions: 0Answers: 0
    Allan,

    I've tried to do some debugging to find out where the problem is (still a newbie tho :)) and I think the bug is in the _fnFeatureHtmlLength function, specifically there's a piece of code

    /* If we have space to show extra rows (backing up from the end point - then do so */
    if ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() )
    {
    oSettings._iDisplayStart = oSettings.fnDisplayEnd() - oSettings._iDisplayLength;
    alert("After iStart " + oSettings._iDisplayStart); <---- BUG
    if ( oSettings._iDisplayStart < 0 )
    {
    oSettings._iDisplayStart = 0;
    }
    }

    The alert shows where I'm seeing the undesired value come in ...

    Can you please confirm whether you agree this is a bug?

    (Re the testcase requirement
    * this is a bug on the datatables.net example at:
    http://www.datatables.net/release-datatables/examples/basic_init/alt_pagination.html and
    any other examples using page number buttons.
    * I wrote a detailed step-by-step description (in prior post to this) on how to reproduce)

    Thank you so much,
    lili
  • lililili Posts: 9Questions: 0Answers: 0
    Alternatively, is there a way to reset to the first page when the user changes the "display length"?
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Ah I see - thanks for clarifying what you are seeing.

    I sort of do agree that this is a bug, but sort of not :-). The reason I have it the way it currently is, is that if you are on the last page of lets say 101 rows, and only a single row is showing, then you change the page length to 50 (from 10), wouldn't you expect to see more than 1 row? I did, and so did a number of others, which is why it is implemented this way.

    DataTables 1.2- (I think - it was a darn long time ago) did it the way you suggest, and it has come up in these forums since, if this should be changed. And possibly it should. I think programmatically it makes more sense - I'm not sure about your 'general' end user. This is something I think would really benefit from some real usability testing, rather than suppositions.

    I have been thinking about changing it back and may do so in 1.10, but I'm far from decided on it yet!

    Allan
  • lililili Posts: 9Questions: 0Answers: 0
    Yay - thank you - thought I was going mad. So basically I'm going to modify the "jquery.dataTables.js" file (for that particular line) from:

    oSettings._iDisplayStart = oSettings.fnDisplayEnd() - oSettings._iDisplayLength;
    to
    oSettings._iDisplayStart = oSettings.fnDisplayEnd() - (oSettings.fnDisplayEnd() % oSettings._iDisplayLength);

    And yes, if I had 101 rows then if page length is 50, I always want my:
    - page 1 to display records #1 - 50
    - page 2 to display records #51-100
    - page 3 to display only record #101. (a lonely row but it's logical for me :))

    I'll finally stop bugging you - but I do hope you'll change it to be the same as above for the next release :) The suggested 1 line fix seems necessary because when I switch between from page #3 to page #2 back to page #3
    - the first time (display as many records as possible i.e. page length 50)
    - the second time it displays only 1
    (page #3 should always be consistent in what it's showing).

    Byeeee!
    lili
  • lililili Posts: 9Questions: 0Answers: 0
    Note, you should tell the people that complained re Datatables 1.2 they're wrong lol! Tell them to:
    1) load a datatable with 101 rows of data
    2) leave the default page size at 10.

    If the user clicks the "last" page button (#11), only 1 row is shown for record #101.

    Therefore when the user changes the page size from 10 to 50, the "last" page button (#3) should ALSO only show record #101.
  • lililili Posts: 9Questions: 0Answers: 0
    edited January 2013
    Actually I found that even with my fix, there's still another bug in a different part of the code that has a similar side effect but this time both the _START_ and _END_ values aren't consistent.

    So going back to the easily available datatable at:
    http://www.datatables.net/release-datatables/examples/basic_init/alt_pagination.html
    with the default page length of 10...

    If you are on page 4, the info correctly displays:
    [quote]Showing 31 to 40 of 57 entries[/quote]

    Then if you change the page length from 10 to 25, it now jumps to page 3 and the info displays:
    [quote]Showing 31 to 55 of 57 entries[/quote]

    Now jump to page 2 and then back to page 3 and the info displays:
    [quote]Showing 51 to 57 of 57 entries[/quote]

    Comparing the last two outputs: sadly there's a mismatch - page 3 should be consistent in it's output, always displaying the exact same records for a particular page length.

    Making one line change to the API is ok but now fixing another one, I'm worried my future team mates are going to hate me from a maintenance perspective. So instead I've managed to come up with a workaround where I'll reset back to the first page every time someone changes the page length.

    [code]
    var ListControl = {}; // global Object container

    ListControl.Pager = function () {

    var self = this; //for use by callback functions to access global vars

    this.selectedPageLength = 0;

    this.oTable = $('#content').dataTable({
    "sPaginationType": "full_numbers",

    "fnPreDrawCallback": function (oSettings) {
    var pg_size_changed = oSettings._iDisplayLength != self.selectedPageLength;
    if (pg_size_changed) {
    oSettings._iDisplayStart = 0; // Reset and go back to the first page
    }
    },

    "fnDrawCallback": function (oSettings) {
    self.selectedPageLength = oSettings._iDisplayLength; //Storing this for use by fnPreDrawCallback
    }
    });
    };
    [/code]

    So basically I'm using a callback to determine when a page length change has occurred... cuz that's my trigger for when to reset back to page #1 :) Hope this helps someone because I couldn't find out how to do this! (Any feedback on the use of callbacks would be appreciated)
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Yeah - that looks about as good as it gets with the callbacks and information available at the moment. You are using private variables there ( _iDisplayLength ) which might well change in future versions though - so something to watch out for. DT 1.10 will present that information in a proper API.

    I've been thinking about the issue you raise, and I'm increasingly thinking that it is a good idea to change. Marked this discussion so I can look at what it will involve when working on 1.10.

    Thanks for brining this up.

    Allan
  • aloaizaaloaiza Posts: 1Questions: 0Answers: 0
    edited March 2013
    I also have this problem, and I "fixed" it changing the original code to this:

    [code]
    /* If we have space to show extra rows (backing up from the end point - then do so */
    if ( oSettings.fnDisplayEnd() == oSettings.fnRecordsDisplay() )
    {
    if (oSettings.fnRecordsDisplay() > oSettings._iDisplayLength) {
    oSettings._iDisplayStart = oSettings.fnDisplayEnd() - (oSettings.fnDisplayEnd() - oSettings._iDisplayLength);
    } else {
    oSettings._iDisplayStart = 0;
    }

    if ( oSettings._iDisplayStart < 0 )
    {
    oSettings._iDisplayStart = 0;
    }
    }
    [/code]

    Regarding my testing, everything else is working fine, but maybe I don't have enough testing scenarios, so would love to get some feedback from you regarding this fix.

    Thanks!
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Looks reasonable - thanks for posting this.

    Allan
This discussion has been closed.