Skip to content

Instantly share code, notes, and snippets.

@JediMindtrick
Forked from flaviaza/README.txt
Last active October 2, 2015 19:44
Show Gist options
  • Save JediMindtrick/7a6b5a684ca3b54e4d65 to your computer and use it in GitHub Desktop.
Save JediMindtrick/7a6b5a684ca3b54e4d65 to your computer and use it in GitHub Desktop.
Twitter bootstrap fixed table header using jQuery
Here is a simple jQuery plugin to make a table header fixed on top of a div when this is scrolled.
Using the code from twitter bootstrap documentation page, this code is customized for table header.
Create the table with following layout -
<div class="row fixed-table">
<div class="table-content">
<table class="table table-striped table-fixed-header" id="mytable">
<thead class="header">
<tr>
<th>Email Address</th>
<th>First Name</th>
<th>Last Name</th>
<th>Administrator</th>
</tr>
</thead>
<tbody>
<tr>
<td>[email protected]</td>
<td>firstname</td>
<td>LastName</td>
<td>Data Column 4</td>
</tr>
...
</tbody>
</table>
</div>
</div>
Add the css from the file "table-fixed-header.css"
To apply it to above table, call -
$('.table-fixed-header').fixedHeader();
You need to assign a height value to ".table-content" into the css file.
var mod = angular.module('FloatingHeader',[]);
mod.directive('floatingHeader',function(){
return function(){
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, elem, attrs, ctrl){
var $body = $(elem).find(".table-container-body"),
$header = $(elem).find(".table-container-header"),
$footer = $(elem).find(".table-container-footer");
// Get ScrollBar width(From: http://bootstrap-table.wenzhixin.net.cn/)
var scrollBarWidth = (function () {
var inner = $('<p/>').addClass('fixed-table-scroll-inner'),
outer = $('<div/>').addClass('fixed-table-scroll-outer'),
w1, w2;
outer.append(inner);
$('body').append(outer);
w1 = inner[0].offsetWidth;
outer.css('overflow', 'scroll');
w2 = inner[0].offsetWidth;
if (w1 === w2) {
w2 = outer[0].clientWidth;
}
outer.remove();
return w1 - w2;
})();
// Scroll horizontal
$body.on('scroll', function () {
$header.scrollLeft($(this).scrollLeft());
$footer.scrollLeft($(this).scrollLeft());
});
// Redraw Header/Footer
var redraw = function() {
var tds = $body.find("> table > tbody > tr:first-child > td");
tds.each(function (i) {
var width = $(this).innerWidth(),
lastPadding = (tds.length -1 == i ? scrollBarWidth : 0);
lastHeader = $header.find("th:eq("+i+")").innerWidth(width + lastPadding);
lastFooter = $footer.find("th:eq("+i+")").innerWidth(width + lastPadding);
});
};
// Selection
$body.find("> table > tbody > tr > td").click(function(e) {
$body.find("> table > tbody > tr").removeClass("info");
$(e.target).parent().addClass('info');
});
// Listen to Resize Window
$(window).resize(redraw);
scope.$watch(attrs.ngModel,function(){
setTimeout(redraw,0);
});
}
};
};
});
<html lang="en">
<head>
<meta charset="utf-8">
<title>Table Fixed Header</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/js/bootstrap.min.js"></script>
<!-- CSS and JS for table fixed header -->
<link rel="stylesheet" href="table-fixed-header.css">
<script src="table-fixed-header.js"></script>
</head>
<body>
<div class="table-container" floating-header ngModel="myModel">
<div class="table-container-header">
<table class="table table-striped table-hover table-condensed table-bordered">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
</table>
</div>
<div class="table-container-body">
<table class="table table-striped table-hover table-condensed table-bordered">
<colgroup>
<col style="width: 20px;"></col>
<col style="width: 100px;"></col>
<col style="width: 200px;"></col>
<col style="width: 150px;"></col>
</colgroup>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<td>3</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<td>4</td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<td>5</td>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<td>6</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<td>7</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<td>8</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<td>9</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
<tr>
<td>10</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
<div class="table-container-footer">
<table class="table table-striped table-hover table-condensed table-bordered">
<tfoot>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</tfoot>
</table>
</div>
</div>
<script language="javascript" type="text/javascript" >
$(document).ready(function(){
// add 30 more rows to the table
var row = $('table#mytable > tbody > tr:first');
for (i=0; i<30; i++) {
$('table#mytable > tbody').append(row.clone());
}
// make the header fixed on scroll
$('.table-fixed-header').fixedHeader();
});
</script>
</body>
</html>
.fixed-table .header-fixed {
position: absolute;
top: 0px;
z-index: 1020; /* 10 less than .navbar-fixed to prevent any overlap */
border-bottom: 2px solid #d5d5d5;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.fixed-table{
display:block;
position:relative;
}
.fixed-table th{
padding: 8px;
line-height: 18px;
text-align: left;
}
.fixed-table .table-content{
display:block;
position: relative;
height: 500px; /*FIX THE HEIGHT YOU NEED*/
overflow-y: auto;
}
.fixed-table .header-copy{
position:absolute;
display: table-row;
top:0;
left:0;
right:0;
}
.fixed-table .header-copy th{
background-color:#fff;
}
var $body = $(".table-container-body"),
$header = $(".table-container-header"),
$footer = $(".table-container-footer");
// Get ScrollBar width(From: http://bootstrap-table.wenzhixin.net.cn/)
var scrollBarWidth = (function () {
var inner = $('<p/>').addClass('fixed-table-scroll-inner'),
outer = $('<div/>').addClass('fixed-table-scroll-outer'),
w1, w2;
outer.append(inner);
$('body').append(outer);
w1 = inner[0].offsetWidth;
outer.css('overflow', 'scroll');
w2 = inner[0].offsetWidth;
if (w1 === w2) {
w2 = outer[0].clientWidth;
}
outer.remove();
return w1 - w2;
})();
// Scroll horizontal
$body.on('scroll', function () {
$header.scrollLeft($(this).scrollLeft());
$footer.scrollLeft($(this).scrollLeft());
});
// Redraw Header/Footer
var redraw = function() {
var tds = $body.find("> table > tbody > tr:first-child > td");
tds.each(function (i) {
var width = $(this).innerWidth(),
lastPadding = (tds.length -1 == i ? scrollBarWidth : 0);
lastHeader = $header.find("th:eq("+i+")").innerWidth(width + lastPadding);
lastFooter = $footer.find("th:eq("+i+")").innerWidth(width + lastPadding);
});
};
// Selection
$body.find("> table > tbody > tr > td").click(function(e) {
$body.find("> table > tbody > tr").removeClass("info");
$(e.target).parent().addClass('info');
});
// Listen to Resize Window
$(window).resize(redraw);
$(document).ready(redraw);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment