Hacking jQuery.scrollTo so it doesn't disappear under Drupal's sticky table header

Submitted by shunting on Thu, 09/10/2009 - 18:08

Only because the syntax took me a bit to figure out --

This is the driver file I'm using to call the JQuery scrollTo effect on some of my content to create bi-directional footnotes between table and legend. Drupal tables have a nice feature (done with JQuery) called sticky headers, which means that the table headers stay visible at the top of the table while the user scrolls down through the rows. This is a real boon with a big table, and some of my tables are big, with lots of footnotes.

Out of the box, the scrollTo function only works on the HTML, so it can't know that Drupal has used JQuery to add a sticky header to a table. As a result, when the user clicks on a footnote in the legend at the bottom of the table, the function scrolls up to the footnote in a table cell that ends up (depending on the z-index) hidden beneath the sticky header, or overprinting in it. Usability issues!

$(function(){ $("#topicmap_index span.topicmap_annotation").click(function(){ var source = $(this).attr("id"); if (source.match('table')) { var up = 0; //crude var target = "#" + source.replace("table", "legend"); } else { var up = 1; var target = "#" + source.replace("legend", "table"); } $.scrollTo(target, { duration: 400, axis: "y", onAfter: function(){ $(target).effect("highlight", { color: "#FDFF00" }, 5000); } }); // This is the hack. If we're going up from the legend, // use scrollTo's relative scrolling to scroll down // out of the way of the sticky header. There's no timing // parameter because we want to hack to be imperceptible. // In a more perfect world, I'd figure out what the depth of // the drupal sticky header is, and use that value instead // of 100px, but this will do for now. if (up == 1) { $.scrollTo('-=100px', { axis: "y", onAfter: function(){ } }); } }); }); The other nice effect is highlighting the target... NOTE Bonus: I use these tables to annotate everything, including the results of various queries. Originally, I had implemented the bidirectional functionality RESTfully (as is the Drupal way), with the footnote markers down to the legend from the cells (and up to the cells from the legends) implemented as HTML links. That demanded a page rebuild, with the page built through hook_nodeapi, which isn't the way drupal thinks about search results: Search results are not nodes! So, not only is this method better for usability, I can use it everywhere, since it's outside the hook system.