Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Think this was all introduced in the rewrite: #1574738: Rewrite tableheader.js.
See screenshots:
- Original header is visible under sticky header (setting a z-index fixes this, but that might open a whole new can of worms
- If for some reason you load the page halfway a table, the sticky table will only show up upon the first scroll. Maybe trigger scroll once on pageload if the table is in the viewport?
- There should be a detach behavior to unregister tables that have been removed/replaced.
- On scroll/resize handlers should be debounced. The inline docs currently state they are debounced to execute every 250ms, but they are actually executed every possible scroll/resize.
Comment | File | Size | Author |
---|---|---|---|
#48 | 1764912-nr-bot.txt | 176 bytes | needs-review-queue-bot |
#40 | D8_TableHeader_helper_functions-1764912-39.patch | 1.8 KB | joseph.olstad |
#40 | interdiff_38_to_39_issue-1764912-39.txt | 597 bytes | joseph.olstad |
#39 | interdiff_37_to_38_issue-1764912-38.txt | 567 bytes | joseph.olstad |
#39 | D8_TableHeader_helper_functions-1764912-38.patch | 1.79 KB | joseph.olstad |
Comments
Comment #1
Kiphaas7 CreditAttribution: Kiphaas7 commentedSo I talked a little bit with nod_ about this, and he said the sticky table creation upon scroll is on purpose, to delay execution as much as possible.
A middleground might be to execute tableHeaderInitHandler unconditionally on attach. Move the 'on scroll' bind to createSticky, after which we can test for checkStickyVisible: if it returns true, trigger scroll on the table.
This way the actual creation and insertion of the sticky table, which I think is the most costly operation, is still delayed if the table is not visible.
If that sounds good, I'll try to whip up a patch.
Comment #1.0
Kiphaas7 CreditAttribution: Kiphaas7 commentedtypos
Comment #2
nod_Comment #3
Kiphaas7 CreditAttribution: Kiphaas7 commentedmade it a task for the last line in the OP, (no detach or events), but if it should be a bug report, fine by me :).
Comment #4
Kiphaas7 CreditAttribution: Kiphaas7 commentedAha!
Seems to be the culprit for the bleed-through. It only happens with links, and the
position: relative;
is responsibleRemoving it from the original table (not the sticky table) seems to fix it.
Comment #5
nod_Comment #6
Kiphaas7 CreditAttribution: Kiphaas7 commentedLooks like a very good and simple solution. Though I would prefer to set offsetTop to null instead of undefined. Semantically makes more sense to me (we set the variable, we just don't know what value it should have).
Should the bleed through bug be deferred to the theme/css folks?
Comment #7
nod_Yeah I wasn't sure, I went for undefined so that it wouldn't break so horribly if someone tries to use it as a number before it's computed.
On the other hand, it's new code, it can be fixed right now :)
Comment #8
Kiphaas7 CreditAttribution: Kiphaas7 commentedIf they want to use it, and it's null at init, they should check if it's not null :). But that's the same if undefined was used... Not checking would be sloppy on their end :P. And yea, the code is still brand new, I doubt anyone is already depending on it :).
Comment #9
nod_tag
Comment #10
Kiphaas7 CreditAttribution: Kiphaas7 commentedJust as a reminder for myself (or others), might want to add this to the patch as well by means of feature testing?
http://drupal.org/node/1440628#comment-6455104
Comment #11
Kiphaas7 CreditAttribution: Kiphaas7 commentedMade a new issue for the bleed-through issue: #1780852: Sticky tableheaders bleed-through.
Comment #12
seutje CreditAttribution: seutje commented@#10: makes sense, we don't want to end up breaking natively supported implementations.
Comment #13
seutje CreditAttribution: seutje commentedafter doing some more analysis, I've come to the conclusion that this won't break native implementations as it'll just swap it to fixed once we're past a certain point.
so if we have consensus on this
undefined
vsnull
thing, this is good to go, yes?Comment #13.0
seutje CreditAttribution: seutje commenteddetach
Comment #14
quicksketchComment #15
quicksketchHi guys, just reviewing the tableheader.js changes from 2012 and thought I'd provide additional input on the changes that I discovered:
- The onScroll behavior says that "This function is throttled to once every 250ms to avoid unnecessary calls." But it is not. Both the onScroll and onResize methods are fired repeatedly with no throttle/debouncing.
- The onScroll call to
this.stickyPosition(null, scrollValue('scrollLeft'));
is having unexpected results. Because in stickyPosition!isNaN(offsetTop)
returns true for a "null" value (see these Mozilla examples). The code seems to expect that null will not be considered a number, but oddly isNaN actually *does* consider null to be a number. Very weird.I'd suggest changing the conditionals to add "&& offsetTop !== null" to prevent the weirdness:
Though maybe there is a better way of checking if a number is not, this StackExchange post seems pretty definitive, but I'm not sure comprehensive checking is really necessary in the first place.
EDIT: Sorry I've noticed that all the problems with isNaN are fixed by using ECMA Script 5's "use strict". Which means we don't have any problem on any browsers except IE9, which doesn't support use strict. http://caniuse.com/use-strict
Comment #16
quicksketchAnother regression: The tableheader behavior will no longer be applied to tables loaded via AJAX, since the use of $(window).one() won't refire when new content is attached. Although you'd have to be replacing a really big table for this issue to occur. Most of the time you'd want to add/replace rows within an existing table rather than replace it, but it could still be an issue in some situations.
Comment #17
nod_For #1 I don't know what I had in mind at the time. Was supposed to be.
For #2 there is already #2269129: Permissions sticky header is not place correctly.
(edit) and for the init are you sure? because to me any new ajax call will bind the tableinit function and it's just that it's executed on the first scroll event that happens. Can you reproduce your bug?
Comment #18
jhedstromComment #19
jain_deepak CreditAttribution: jain_deepak commentedRe Rolled patch
Comment #20
jain_deepak CreditAttribution: jain_deepak commentedComment #21
pwieck CreditAttribution: pwieck commentedComment #24
nod_Comment #25
Manjit.Singhrerolling a patch :)
Comment #26
Manjit.SinghComment #27
googletorp CreditAttribution: googletorp as a volunteer commentedComment #28
mgiffordNeeds re-roll.
Comment #29
droplet CreditAttribution: droplet commentedNot sure if it's still exist.
Can't reproduce (also @see #17)
this is make sense.
For page with many sticky tables, it helps a bit. If only one or two, it's slightly bad for UX IMO.
I think we should open new issues for each problem.
Note that: No re-roll is needed. I reviewed the patch and that's not right approach now.
Comment #36
maximpodorov CreditAttribution: maximpodorov commentedWhat about the invalidation of all tables on each DOM change?
Comment #38
joseph.olstadI'm going to hijack this issue, I'm proposing some improvements in the name of helper functions.
Imagine your sticky table header works great on first page load, then you grab some table from ajax, replace the table in the DOM with the new table from ajax, well, that just broke the references in the tables collection in Drupal.TableHeader.tables
So, to solve this, I've added three helper functions, one is called Drupal.TableHeader.validateReferences()
what this function does is remove the unreferenced tables in the collection of Drupal.TableHeader.tables (tables that are no longer found in the DOM)
This explains how , if you call recalculateSticky with broken references (tables no longer present in the DOM) the table cell widths will all be returned 0 , and the whole recalculateSticky will be broken.
So to solve this, you call Drupal.TableHeader.validateReferences() and then re-initialise by calling Drupal.TableHeader.addTable(tableSelectorParam);
see patch
Also, if you have multiple sticky headers on a page, I found it useful to add another function called Drupal.TableHeader.recalculateStickys(); rather than recalculateSticky on one item , this does all of them in a for loop.
So three functions added altogether.
This is 100% backwards compatible.
Works very well now that I finally figured out how to use this library.
I'd like to provide some example code at some point as well, however the above instructions should be helpful, would probably be good to add comments to the tableheader.js file with this explanation , or add a link to documentation with an example or two.
a quick example
make a global scope variable , set it to false
like
then as an example, some js functions I use:
in the function initlialiseStickyTableHeader() you do something like this:
Comment #39
joseph.olstadsee comment # 38 for a verbose explanation.
#1764912-38: Fix regressions and further improve tableheader.js
interdiff shows minor change, removing setTimeout (not needed).
attaching updated patch
Comment #40
joseph.olstadsee comment # 38 for a verbose explanation.
#1764912-38: Fix regressions and further improve tableheader.js
interdiff shows minor change, putting comment before code.
attaching updated patch
Comment #41
joseph.olstad@Quicksketch, these helper functions and detailed explanation in comment #38 (with examples) explain and provide a strategy to deal with and explain what happens when doing ajax calls (replacing a table for example) what you describe in #16.
see comment #38 and patch 39
#1764912-38: Fix regressions and further improve tableheader.js
Comment #48
needs-review-queue-bot CreditAttribution: needs-review-queue-bot as a volunteer commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.