- Patch #112605 by Steven: sticky table headers.
parent
018bd034c8
commit
f996fd9568
|
@ -761,6 +761,9 @@ function theme_table($header, $rows, $attributes = array(), $caption = NULL) {
|
||||||
|
|
||||||
// Format the table header:
|
// Format the table header:
|
||||||
if (count($header)) {
|
if (count($header)) {
|
||||||
|
// Include JS for sticky headers.
|
||||||
|
drupal_add_js('misc/tableheader.js');
|
||||||
|
|
||||||
$ts = tablesort_init($header);
|
$ts = tablesort_init($header);
|
||||||
$output .= ' <thead><tr>';
|
$output .= ' <thead><tr>';
|
||||||
foreach ($header as $cell) {
|
foreach ($header as $cell) {
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
// Global Killswitch
|
||||||
|
if (Drupal.jsEnabled) {
|
||||||
|
// Keep track of all header cells.
|
||||||
|
var cells = [];
|
||||||
|
|
||||||
|
// Attach to all headers.
|
||||||
|
$(document).ready(function() {
|
||||||
|
var z = 0;
|
||||||
|
$('table thead').each(function () {
|
||||||
|
// Find table height.
|
||||||
|
var table = $(this).parent('table')[0];
|
||||||
|
var height = $(table).addClass('sticky-table').height();
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
// Find all header cells.
|
||||||
|
$('th', this).each(function () {
|
||||||
|
|
||||||
|
// Ensure each cell has an element in it.
|
||||||
|
var html = $(this).html();
|
||||||
|
if (html == ' ') {
|
||||||
|
html = ' ';
|
||||||
|
}
|
||||||
|
if ($(this).children().size() == 0) {
|
||||||
|
html = '<span>'+ html +'</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone and wrap cell contents in sticky wrapper that overlaps the cell's padding.
|
||||||
|
$('<div class="sticky-header" style="position: fixed; visibility: hidden; top: 0px;">'+ html +'</div>').prependTo(this);
|
||||||
|
var div = $('div.sticky-header', this).css({
|
||||||
|
'marginLeft': '-'+ $(this).css('paddingLeft'),
|
||||||
|
'marginRight': '-'+ $(this).css('paddingRight'),
|
||||||
|
'paddingLeft': $(this).css('paddingLeft'),
|
||||||
|
'paddingTop': $(this).css('paddingTop'),
|
||||||
|
'paddingBottom': $(this).css('paddingBottom'),
|
||||||
|
'z-index': ++z
|
||||||
|
})[0];
|
||||||
|
cells.push(div);
|
||||||
|
|
||||||
|
// Adjust width to fit cell/table.
|
||||||
|
var ref = this;
|
||||||
|
if (!i++) {
|
||||||
|
// The first cell is as wide as the table to prevent gaps.
|
||||||
|
ref = table;
|
||||||
|
div.wide = true;
|
||||||
|
}
|
||||||
|
$(div).css('width', parseInt($(ref).width())
|
||||||
|
- parseInt($(div).css('paddingLeft')) +'px');
|
||||||
|
|
||||||
|
// Get position and store.
|
||||||
|
div.cell = this;
|
||||||
|
div.table = table;
|
||||||
|
div.stickyMax = height;
|
||||||
|
div.stickyPosition = Drupal.absolutePosition(this).y;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Track scrolling.
|
||||||
|
var scroll = function() {
|
||||||
|
$(cells).each(function () {
|
||||||
|
// Fetch scrolling position.
|
||||||
|
var scroll = document.documentElement.scrollTop || document.body.scrollTop;
|
||||||
|
var offset = scroll - this.stickyPosition - 4;
|
||||||
|
if (offset > 0 && offset < this.stickyMax - 100) {
|
||||||
|
$(this).css('visibility', 'visible');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(this).css('visibility', 'hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
$(window).scroll(scroll);
|
||||||
|
$(document.documentElement).scroll(scroll);
|
||||||
|
|
||||||
|
// Track resizing.
|
||||||
|
var time = null;
|
||||||
|
var resize = function () {
|
||||||
|
// Ensure minimum time between adjustments.
|
||||||
|
if (time) {
|
||||||
|
clearTimeout(time);
|
||||||
|
time = null;
|
||||||
|
}
|
||||||
|
time = setTimeout(function () {
|
||||||
|
|
||||||
|
// Precalculate table heights
|
||||||
|
$('table.sticky-table').each(function () {
|
||||||
|
this.height = $(this).height();
|
||||||
|
})
|
||||||
|
|
||||||
|
$(cells).each(function () {
|
||||||
|
// Get position.
|
||||||
|
this.stickyPosition = Drupal.absolutePosition(this.cell).y;
|
||||||
|
this.stickyMax = this.table.height;
|
||||||
|
|
||||||
|
// Reflow the cell.
|
||||||
|
var ref = this.cell;
|
||||||
|
if (this.wide) {
|
||||||
|
// Resize the first cell to fit the table.
|
||||||
|
ref = this.table;
|
||||||
|
}
|
||||||
|
$(this).css('width', parseInt($(ref).width())
|
||||||
|
- parseInt($(this).css('paddingLeft')) +'px');
|
||||||
|
});
|
||||||
|
}, 250);
|
||||||
|
};
|
||||||
|
$(window).resize(resize);
|
||||||
|
}
|
|
@ -390,3 +390,10 @@ html.js .resizable-textarea textarea {
|
||||||
tr.selected td {
|
tr.selected td {
|
||||||
background: #ffc;
|
background: #ffc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Floating header for tableheader.js
|
||||||
|
*/
|
||||||
|
thead div.sticky-header {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
|
@ -170,6 +170,10 @@ thead th {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thead div.sticky-header {
|
||||||
|
border-bottom: 2px solid #d3e7f4;
|
||||||
|
}
|
||||||
|
|
||||||
th a:link, th a:visited {
|
th a:link, th a:visited {
|
||||||
color: #6f9dbd;
|
color: #6f9dbd;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue