How to stay on current page after re-draw?

How to stay on current page after re-draw?

SDCSDC Posts: 8Questions: 0Answers: 0
edited September 2009 in General
Hi Allan,

Many thanks again for the Datatables plugin, and thanks for helping me through a past problem.

At the moment I have a table which is using jEditable to edit columns and allows you to hop from one column to the next (instead of selecting each individual column).

One minor problem I've encountered is b/c a redraw happens (this is server side data if that helps), if I have more than one page of data and I'm past page 1, I end up advancing to the next column, same row...but on page 1.

I am thinking there is a way to capture where I am and convey that to the redraw callback, but I am not sure how. Do I need to do something w/ fnSettings and such to save my previous start display val? I've tried a couple things to no avail.

Thanks,
Steve

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Hi Steve,

    Interesting one. iDisplayStart is the variable which DataTables uses to say where it should start drawing the table, and it must be sending this as 0 to the server-side process on each draw after an update. I'm not sure what would cause that with server-side processing... Do you have a link which will show us the problem?

    Thanks,
    Allan
  • SDCSDC Posts: 8Questions: 0Answers: 0
    Hi Allan,

    Unfortunately at the moment this is just me working on my home machine, so I don't have a link for you. I might put something up, but I'd probably use Google App Engine and as I haven't used that for a bit it might take a bit to get back into it.

    I did actually check the jeditable example on the Datatables site, and it seems to do the same thing - if you edit page 2 it jumps back to page 1. Not as big of a deal in that case but I was worried it had something to do w/ getting the data from the server.

    There is a workaround - if you do a search that limits the records on the screen to one page, you're fine. I was just wondering is there a way to 'save your place'.

    Also if it helps these are the parameters for the table:

    "bProcessing": true, // shows 'processing' label
    "bServerSide": true,
    "sAjaxSource": "/cds/",
    "bStateSave": true, // presumably saves state for reloads

    Thanks,
    Steve
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    edited September 2009
    Hi Steve,

    I think I know what is causing this. When the data is submitted an fnDraw() is called, DataTables will do s resort and a refilter with the new data (the new data might mean the sorting order changes for example), and as part of it's sorting method it will always return you to the first page! This makes sense for sorting using the column headers, but perhaps not when doing an update like this...

    Using DOM based data you can store the state of iDisplayStart, but this doesn't really work with server-side processing since an extra XHR will be needed and the update would be visible to the end user.

    I think what is really called for here is so method by which to disable this 'reset to first page' behaviour in DataTables so you, the developer, and enable or disable this as required. I'll look into this for a future release, but for now, you could have a little hack in the DataTables script. Lines 3038 and 3337 are the two in question (although I think only the second will actually be needed for your situation). Just wrap these lines in global variables which you can toggle as needed. ie.:

    [code]
    /* in Datatables */
    if ( bResetDisplay )
    {
    oSettings._iDisplayStart = 0;
    }
    [/code]
    and

    [code]
    /* when updating the table */
    bResetDisplay = false; /* override default behaviour */
    oTable.fnDraw();
    bResetDisplay = true; /* restore default behaviour */
    [/code]
    Regards,
    Allan
  • SDCSDC Posts: 8Questions: 0Answers: 0
    Hooray! It works!

    Many thanks!

    Beer money coming your way...

    Steve
  • atcatc Posts: 14Questions: 0Answers: 0
    Hey cool! This is just what I needed.

    I've found a glitch, though: if I'm on a page other than 1, the search function is screwed up. It gives me results such as "Showing 21 to 9 of 9 entries (filtered from 116 total entries)"....

    I've double-checked using the un-modified datatables js, and this problem does not occur, so I'm pretty positive it's the result of those changes to 3038 and 3337 and not something else in my code.

    Ideas?

    As always, thanks!

    Alison
  • SDCSDC Posts: 8Questions: 0Answers: 0
    That's a bit odd. I was just playing w/ the stuff I was working on and I don't see that problem. I tried a couple searches and a couple different non page one pages.
  • atcatc Posts: 14Questions: 0Answers: 0
    Hm... Still having the problem and having difficulty trouble-shooting. I feel like I need to figure out a way to better control the bResetDisplay variable so that, in the event of a Search, it's set to true, but in the case of editing/updating is not. I'm declaring the variable right at the top of the datatables.js and if I set it to true there, there's no problem with the search, but of course it then resets to page one in the case of an update as well. To be honest, I feel like I don't completely understand the code modifications around line 3337 so I'm not sure how to refine it. Any help would be very much appreciated.

    Best,
    Alison
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Hi Alison,

    The answer to your question will depend on what code you already have. Basically, if you want the page to be re-drawn, and stay on the current page do:

    [code]
    bResetDisplay = false; /* override default behaviour */
    oTable.fnDraw();
    bResetDisplay = true; /* restore default behaviour */
    [/code]
    but if you want it to jump back to the start, do:
    [code]
    oTable.fnDraw();
    [/code]
    with the modification of course :-). It's just a simple case of if DataTables should reset the display back to zero or not.

    Regards,
    Allan
  • atcatc Posts: 14Questions: 0Answers: 0
    edited September 2009
    Hey Allan,

    I seem to be running in circles -- I'm sure what you just wrote is perfectly clear, but I can't make it work. No matter which way I go I seem to only be able to get one piece of it to work: either it stays on the current page OR the search/filter function works... Because for the filtered results to display properly, it has to reset to page 1, right?

    The modification in the main datatables javascript, from
    [code]
    oSettings._iDisplayStart = 0;
    [/code]
    to
    [code]
    if ( bResetDisplay )
    {
    oSettings._iDisplayStart = 0;
    }
    [/code]
    makes sense to me.

    It's that second modification within _fnSort (the lines you reiterate above) that has got me stumped. It seems like what I really need is for bResetDisplay to be set to true except when updating with jeditable. If I include those three lines in the main js then it never resets to page 1.
    So I tried setting bResetDisplay to true at the top of datatables.js (also tried setting that default various places in my table-create script) and including a line in my editable callback code like this:
    [code]
    $('#thematrix tbody td.editable').editable('/clients/codelib/update_matrix.php', {
    "tooltip" : 'Double-click to edit...',
    "placeholder": '',
    "type" : 'mce',
    "submit" : 'Submit',
    "cancel" : 'Cancel',
    "cssclass" : 'expanding',
    "indicator" : 'saving',
    "width" : '250px',
    "height" : '200px',
    "event" : 'dblclick',
    "callback": function( sValue, y ) {
    bResetDisplay = false; /* override default behaviour */
    oMatrix1.fnDraw();
    bResetDisplay = true; /* restore default behaviour */
    var aPos = oMatrix1.fnGetPosition( this );
    var theID = $(this).attr('id');
    oMatrix1.fnUpdate( sValue, aPos[0], aPos[1] );
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    alert( "XMLHttpRequest: " + XMLHttpRequest );
    alert( "errorThrown: " + errorThrown );
    alert( "textStatus: " + textStatus );
    }
    } );
    [/code]

    but it still pops back to page 1...

    Argh! I'm totally stumped. I much appreciate your help and your patience!

    Best,
    A
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    edited September 2009
    Hi Alison,

    I rather suspect that it is the fnUpdate() which is causing your grief. It will do an automatic redraw unless you tell it otherwise: http://datatables.net/api#fnUpdate - parameter 4 :-)

    As such, it might work if you do something like this:

    [code]
    $('#thematrix tbody td.editable').editable('/clients/codelib/update_matrix.php', {
    "tooltip" : 'Double-click to edit...',
    "placeholder": '',
    "type" : 'mce',
    "submit" : 'Submit',
    "cancel" : 'Cancel',
    "cssclass" : 'expanding',
    "indicator" : 'saving',
    "width" : '250px',
    "height" : '200px',
    "event" : 'dblclick',
    "callback": function( sValue, y ) {
    var aPos = oMatrix1.fnGetPosition( this );
    var theID = $(this).attr('id');
    bResetDisplay = false; /* override default behaviour */
    oMatrix1.fnUpdate( sValue, aPos[0], aPos[1] );
    bResetDisplay = true; /* restore default behaviour */
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    alert( "XMLHttpRequest: " + XMLHttpRequest );
    alert( "errorThrown: " + errorThrown );
    alert( "textStatus: " + textStatus );
    }
    } );
    [/code]
    Or you could try:

    [code]
    $('#thematrix tbody td.editable').editable('/clients/codelib/update_matrix.php', {
    "tooltip" : 'Double-click to edit...',
    "placeholder": '',
    "type" : 'mce',
    "submit" : 'Submit',
    "cancel" : 'Cancel',
    "cssclass" : 'expanding',
    "indicator" : 'saving',
    "width" : '250px',
    "height" : '200px',
    "event" : 'dblclick',
    "callback": function( sValue, y ) {
    var aPos = oMatrix1.fnGetPosition( this );
    var theID = $(this).attr('id');
    oMatrix1.fnUpdate( sValue, aPos[0], aPos[1], false );
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    alert( "XMLHttpRequest: " + XMLHttpRequest );
    alert( "errorThrown: " + errorThrown );
    alert( "textStatus: " + textStatus );
    }
    } );
    [/code]
    Which would be better, since it doesn't involve editing the core.

    Hope that does the trick!
    Allan
  • atcatc Posts: 14Questions: 0Answers: 0
    You're my hero!!! That second option works like a charm and is a much simpler solution. Also I now have a better understanding of fnUpdate. Thank you so much! More beer bucks coming your way!

    Best,
    Alison
  • jhoguetjhoguet Posts: 3Questions: 0Answers: 0
    Allan -

    I came up with a rather simple plugin that so far seems to be working for me.

    [code]
    $.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
    var before = oSettings._iDisplayStart;

    //redraw to account for filtering and sorting
    oSettings.oApi._fnReDraw(oSettings);

    //iDisplayStart has been reset to zero - so lets change it back
    oSettings._iDisplayStart = before;

    oSettings.oApi._fnCalculateEnd(oSettings);

    //draw the page for the new page
    oSettings.oApi._fnDraw(oSettings);
    };
    [/code]

    I don't normally post things like this, but there seems to be a demand - would you mind looking at it and verifying that I am not using some internal incorrectly.

    My hope is that this might satisfy some of your audience and allow you to focus on other parts of your backlog.

    thanks,

    Jon
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Hi Jon,

    Nice one! The function looks just about perfect to me - thanks very much indeed for sharing it with us :-). I've put it up on the API plug-ins page, as I'm sure it will be useful for many people: http://datatables.net/plug-ins/api#fnStandingRedraw . If you would like the credit altered (link, changed etc) please just give me a shout.

    Regards,
    Allan
  • jhoguetjhoguet Posts: 3Questions: 0Answers: 0
    Allan,

    Here is a slight modification to make it also work for server side.
    [code]
    (function($){
    $.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
    //redraw to account for filtering and sorting
    // concept here is that (for client side) there is a row got inserted at the end (for an add)
    // or when a record was modified it could be in the middle of the table
    // that is probably not supposed to be there - due to filtering / sorting
    // so we need to re process filtering and sorting
    // BUT - if it is server side - then this should be handled by the server - so skip this step
    if(oSettings.oFeatures.bServerSide === false){
    var before = oSettings._iDisplayStart;
    oSettings.oApi._fnReDraw(oSettings);
    //iDisplayStart has been reset to zero - so lets change it back
    oSettings._iDisplayStart = before;
    oSettings.oApi._fnCalculateEnd(oSettings);
    }

    //draw the 'current' page
    oSettings.oApi._fnDraw(oSettings);
    };
    })(jQuery);
    [/code]
  • allanallan Posts: 63,498Questions: 1Answers: 10,470 Site admin
    Hi Jon,

    Thanks very much for the update! I've just posted it on the API plug-ins page: http://datatables.net/plug-ins/api#fnStandingRedraw

    Regards,
    Allan
This discussion has been closed.