Skip to content
Snippets Groups Projects
Commit f996fd95 authored by Dries Buytaert's avatar Dries Buytaert
Browse files

- Patch #112605 by Steven: sticky table headers.

parent 018bd034
No related branches found
No related tags found
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
......@@ -761,6 +761,9 @@ function theme_table($header, $rows, $attributes = array(), $caption = NULL) {
// Format the table header:
if (count($header)) {
// Include JS for sticky headers.
drupal_add_js('misc/tableheader.js');
$ts = tablesort_init($header);
$output .= ' <thead><tr>';
foreach ($header as $cell) {
......
// $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 = '&nbsp;';
}
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 {
background: #ffc;
}
/*
** Floating header for tableheader.js
*/
thead div.sticky-header {
background: #fff;
}
......@@ -170,6 +170,10 @@ thead th {
font-weight: bold;
}
thead div.sticky-header {
border-bottom: 2px solid #d3e7f4;
}
th a:link, th a:visited {
color: #6f9dbd;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment