Mottie / tablesorter

Github fork of Christian Bach's tablesorter plugin + awesomeness ~
https://mottie.github.io/tablesorter/docs/
2.61k stars 754 forks source link

Stickyheaders IE and Chrome #1291

Open mtgtnt opened 8 years ago

mtgtnt commented 8 years ago

I'm back :(

I am unable to find a solution to the the sticky header incorrectly aligning in IE and Chrome. FF is fine. See http://jsbin.com/kumanimuli/1/edit?output

I have tried a wrapper div but it did not help. It seems something with it incorrectly calculating left when margin auto, but im only guessing now. It's all looking like a big blob of text now after 6 hours of trying a multitude of options.

I am also unable to find how to keep the background arrow images to also show in the sticky. You will see this in the jsbin.

ps. I tried to use jsfiddle but it wont load in my IE so i had to resort to jsbin.

Mottie commented 8 years ago

Hi @mtgtnt!

The main issue is the margin: auto shouldn't be applied to the table. Instead apply it to the outer wrapper and make sure to set a width

#contacts {
  margin: 0 auto; /* removed from .pivot definition */
  width: 1255px;
}

Because the main table has an ID, the background arrows are only being applied to the main table through css. The cloned header will also have an ID, but to keep it unique, a "-sticky" is added to the end (see the stickyHeaders_cloneId option). This also needs a css update:

#sortcontacts thead, #sortcontacts-sticky thead {
  cursor: pointer;
}
#sortcontacts thead th.up, #sortcontacts-sticky thead th.up { ... }
#sortcontacts thead th.down, #sortcontacts-sticky thead th.down { ... }

No changes to the javascript are needed. That should get everything working - see updated demo.

mtgtnt commented 8 years ago

Thank you so much. I swear I tried that with the wrapper. I know I did margin auto there and width, but i have a weird feeling i didnt try both together for some reason.

As for the stickyHeaders_cloneID option, now I understand how it works. I was close, just didnt get it into the css.

mtgtnt commented 8 years ago

Is there an equivilant to stickyHeaders_filteredToTop for sorting? When sorting it can scroll to top.

Mottie commented 8 years ago

When you sort, the filter should be re-applied, so the stickyHeaders_filteredToTop should also work when sorting. Is it not?

mtgtnt commented 8 years ago

No it is not. I use both the group and stickyheaders. It does not scroll to top with or without group widget.

Mottie commented 8 years ago

Oh, I forgot you're not using the filter widget.

You can add this bit of code to set the scroll position after a sort has completed (updated demo)

$("#sortcontacts").on('sortEnd', function() {
  $(window).scrollTop($(this).scrollTop());
});
mtgtnt commented 8 years ago

I have multiple tables on one page and would like just that table to scroll to top. I have $('html, body').animate({scrollTop: $(this).offset().top}, 1000), was just missing the 'sortEnd'. With a select menu change, each table is updated with ajax. As each is loaded .trigger("update") jumps around the page leaving an undesired effect.

$("#sortcontactsA, #sortcontactsB, #sortcontactsC").on('sortEnd', function() {
    $('html, body').animate({scrollTop: $(this).offset().top}, 1000);
});

This works perfectly on each table once all is loaded. Is there a way to not allow this scroll on the update trigger?

Mottie commented 8 years ago

Add a check to see if the table is in the viewport, and only scroll that table.

mtgtnt commented 8 years ago

With using grouping, most are in viewport. So with at least one table not in viewport, it will scroll the page up and down until all are loaded and depending on the amount of data to return from each ajax call, it can be in a different order for each select item. I am testing to find a way to not allow the sortEnd if update trigger. Not having luck so far.

Any other suggestions?

Mottie commented 8 years ago

Maybe add a flag before you use ajax, and clear it on a timer after the update complete event:

// inside IIFE but outside any code
var scrollFlag = true;

// inside successful ajax; before triggering "update"
scrollFlag = false;

// bindings on table
$("#sortcontacts")
  .on("updateComplete", function() {
    // give layout time to redraw
    setTimeout(function() {
      scrollFlag = true;
    }, 500);
  })
  .on("sortEnd", function() {
    if (scrollFlag) {
      $('html, body').animate({scrollTop: $(this).offset().top}, 1000);
    }
  });

It's not the prettiest thing in the world, but it should work. I'll see what I can do about including some internal flags.

mtgtnt commented 8 years ago

Everything you put looked great but didnt work. I modified everything until I saw the issue. A mix of scrollflag and scrollFlag. Once I saw it, reverted to the original code, changed the timeout to 6000 as there is a LOT of data, it works PERFECT. I was so tired last night so I gave up looking for any other options. I saw the "updateComplete" but never thought to try it.

Is there any way to be notified when you have included an internal flag?

And again, thank you so much for taking the time with me on this. I am still learning.

Mottie commented 8 years ago

You're welcome! LOL and I just fixed the camel casing in my code above, sorry!

Given that I'm going out of town for a month, I probably won't get around to adding the internal flag until after I get back. I'll leave this issue open as a reminder, and close it once it's done. You should get a notification.