Search code examples
javascriptjquerytablesorter

tablesorter (mottie fork) / restore tbody scroll pos - properly?


I search for a better or official way to restore the scroll position of my tbody table content.

tablesorter 2.26.6
jquery 2.2.3

I do not use tablesorter plugin pager, because all my content is scrollable (not with pages) and I have scroll bars without the scroller plugin. Maybe this is my problem?

Code for tablesorter:

$(document).ready(function () {
   $("#fsi_srvovtable")
    .tablesorter({
      theme: "bootstrap",
      widthFixed: true,
      showProcessing   : true, 
      headerTemplate: '{content} {icon}',
      widgets: ["storage", "saveSort", "uitheme", "filter"],
      headers: { 0: { 
                        sorter: false, 
                        filter: false
                    }
               },
      widgetOptions: {
         filter_reset : 'button.reset',
         filter_hideFilters: false,
         filter_ignoreCase: true,
         filter_saveFilters: true,
         filter_cssFilter: "form-control",
      }
    })
});

The table body has a height of 663px and the content is scrollable.

To save the scroll position I found some tips on stackoverflow:

   $("#fsi_srvoverview").on("scroll", function() {
      $("#fsi_scroll").html($("#fsi_srvoverview")[0].scrollTop);
      if (localStorage) {
         var posOverview = localStorage["fsi_srvoverview_scroll"];
         if (posOverview) {
            localStorage.removeItem("fsi_srvoverview_scroll");
         }
         localStorage["fsi_srvoverview_scroll"] = $("#fsi_srvoverview")[0].scrollTop;
         return true;
      }
      else {
         return false;
      }
   });

After all resorting or filtering I want to restore the scroll position of my table.

I try .bind("updateComplete",... and $(window).load(function(){ or $(window).ready(function(){ to restore the scroll position of my table body. But this does not work, only if I insert a window.alert popup message before the restore function (I think now it is sure that it is the last call).

On the website http://callmenick.com/post/check-if-everything-loaded-with-javascript I found a hint and build this:

   $(window).load(function(){
      var everythingLoaded = setInterval(function() {
         if (/loaded|complete/.test(document.readyState)) {
            clearInterval(everythingLoaded);
            var posOverview = localStorage["fsi_srvoverview_scroll"];
            if (posOverview) {
               $("#fsi_srvoverview")[0].scrollTop = posOverview;
            }
         }
      }, 10);
   });      

That works - but the table is jumping to the start/beginning and than to the position.

I look for a parameter to disable this jump or is there a better way to restore the scroll position with tablesorter?

Regards
Jochen


Solution

  • The reason the scroll position changes is because during sorting, the tbody is detached, so the table height is automatically adjusted by the browser. Once the tbody is restored, the scrollbar doesn't revert back to it's previous value.

    I haven't tested this method, but if you save the scroll position in a "scrollStart" and "filterStart" event, then restore it on "filterEnd" and "sortEnd", it should work. Here is the sample code:

    var top, left,
      $win = $(window);
    $('table')
      .on('sortStart filterStart', function() {
        left = $win.scrollLeft();
        top = $win.scrollTop();
      })
      .on('sortEnd filterEnd', function() {
        $win.scrollLeft(left);
        $win.scrollTop(top);
      })
      .tablesorter();
    

    The "updateComplete" event should only be firing after the table gets updated ("update" event); if the sortEnd filterEnd combo doesn't seem to be working, try replacing it with tablesorter-ready.