| 1 |
// $Id: tableheader.js,v 1.27 2009/09/20 19:14:40 dries Exp $
|
| 2 |
(function ($) {
|
| 3 |
|
| 4 |
Drupal.tableHeaderDoScroll = function () {
|
| 5 |
if ($.isFunction(Drupal.tableHeaderOnScroll)) {
|
| 6 |
Drupal.tableHeaderOnScroll();
|
| 7 |
}
|
| 8 |
};
|
| 9 |
|
| 10 |
Drupal.behaviors.tableHeader = {
|
| 11 |
attach: function (context, settings) {
|
| 12 |
// This breaks in anything less than IE 7. Prevent it from running.
|
| 13 |
if ($.browser.msie && parseInt($.browser.version, 10) < 7) {
|
| 14 |
return;
|
| 15 |
}
|
| 16 |
|
| 17 |
// Keep track of all cloned table headers.
|
| 18 |
var headers = [];
|
| 19 |
|
| 20 |
$('table.sticky-enabled thead', context).once('tableheader', function () {
|
| 21 |
// Clone the table header so it inherits original jQuery properties. Hide
|
| 22 |
// the table to avoid a flash of the header clone upon page load.
|
| 23 |
var headerClone = $(this).clone(true).hide().insertBefore(this.parentNode).wrap('<table class="sticky-header"></table>').parent().css({
|
| 24 |
position: 'fixed',
|
| 25 |
top: '0px'
|
| 26 |
});
|
| 27 |
|
| 28 |
headerClone = $(headerClone)[0];
|
| 29 |
headers.push(headerClone);
|
| 30 |
|
| 31 |
// Store parent table.
|
| 32 |
var table = $(this).parent('table')[0];
|
| 33 |
headerClone.table = table;
|
| 34 |
// Finish initializing header positioning.
|
| 35 |
tracker(headerClone);
|
| 36 |
// We hid the header to avoid it showing up erroneously on page load;
|
| 37 |
// we need to unhide it now so that it will show up when expected.
|
| 38 |
$(headerClone).children('thead').show();
|
| 39 |
|
| 40 |
$(table).addClass('sticky-table');
|
| 41 |
});
|
| 42 |
|
| 43 |
// Define the anchor holding var.
|
| 44 |
var prevAnchor = '';
|
| 45 |
|
| 46 |
// Track positioning and visibility.
|
| 47 |
function tracker(e) {
|
| 48 |
// Reset top position of sticky table headers to the current top offset.
|
| 49 |
var topOffset = Drupal.settings.tableHeaderOffset ? eval(Drupal.settings.tableHeaderOffset + '()') : 0;
|
| 50 |
$('.sticky-header').css('top', topOffset + 'px');
|
| 51 |
// Save positioning data.
|
| 52 |
var viewHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
|
| 53 |
if (e.viewHeight != viewHeight) {
|
| 54 |
e.viewHeight = viewHeight;
|
| 55 |
e.vPosition = $(e.table).offset().top - 4 - topOffset;
|
| 56 |
e.hPosition = $(e.table).offset().left;
|
| 57 |
e.vLength = e.table.clientHeight - 100;
|
| 58 |
// Resize header and its cell widths.
|
| 59 |
var parentCell = $('th', e.table);
|
| 60 |
$('th', e).each(function (index) {
|
| 61 |
var cellWidth = parentCell.eq(index).css('width');
|
| 62 |
// Exception for IE7.
|
| 63 |
if (cellWidth == 'auto') {
|
| 64 |
cellWidth = parentCell.get(index).clientWidth + 'px';
|
| 65 |
}
|
| 66 |
$(this).css('width', cellWidth);
|
| 67 |
});
|
| 68 |
$(e).css('width', $(e.table).css('width'));
|
| 69 |
}
|
| 70 |
|
| 71 |
// Track horizontal positioning relative to the viewport and set visibility.
|
| 72 |
var hScroll = document.documentElement.scrollLeft || document.body.scrollLeft;
|
| 73 |
var vOffset = (document.documentElement.scrollTop || document.body.scrollTop) - e.vPosition;
|
| 74 |
var visState = (vOffset > 0 && vOffset < e.vLength) ? 'visible' : 'hidden';
|
| 75 |
$(e).css({ left: -hScroll + e.hPosition + 'px', visibility: visState });
|
| 76 |
|
| 77 |
// Check the previous anchor to see if we need to scroll to make room for the header.
|
| 78 |
// Get the height of the header table and scroll up that amount.
|
| 79 |
if (prevAnchor != location.hash) {
|
| 80 |
if (location.hash != '') {
|
| 81 |
var scrollLocation = $('td' + location.hash).offset().top - $(e).height();
|
| 82 |
$('body, html').scrollTop(scrollLocation);
|
| 83 |
}
|
| 84 |
prevAnchor = location.hash;
|
| 85 |
}
|
| 86 |
}
|
| 87 |
|
| 88 |
// Only attach to scrollbars once, even if Drupal.attachBehaviors is called
|
| 89 |
// multiple times.
|
| 90 |
$('body').once(function () {
|
| 91 |
$(window).scroll(Drupal.tableHeaderDoScroll);
|
| 92 |
$(document.documentElement).scroll(Drupal.tableHeaderDoScroll);
|
| 93 |
});
|
| 94 |
|
| 95 |
// Track scrolling.
|
| 96 |
Drupal.tableHeaderOnScroll = function () {
|
| 97 |
$(headers).each(function () {
|
| 98 |
tracker(this);
|
| 99 |
});
|
| 100 |
};
|
| 101 |
|
| 102 |
// Track resizing.
|
| 103 |
var time = null;
|
| 104 |
var resize = function () {
|
| 105 |
// Ensure minimum time between adjustments.
|
| 106 |
if (time) {
|
| 107 |
return;
|
| 108 |
}
|
| 109 |
time = setTimeout(function () {
|
| 110 |
$('table.sticky-header').each(function () {
|
| 111 |
// Force cell width calculation.
|
| 112 |
this.viewHeight = 0;
|
| 113 |
tracker(this);
|
| 114 |
});
|
| 115 |
// Reset timer.
|
| 116 |
time = null;
|
| 117 |
}, 250);
|
| 118 |
};
|
| 119 |
$(window).resize(resize);
|
| 120 |
}
|
| 121 |
};
|
| 122 |
|
| 123 |
})(jQuery);
|