Bootstrap Table Fixed Header with Footer
This is to mimic a Table with fixed header at top and a footer.
Different from other options in the internet, this is not automatic layout. You have to build the HTML following the structure above.
This table has rounded corners and the CSS is customized to remove double borders.
Columns width can be px or %, the table-layout is fixed. The table can scroll horizontally and vertically. Fixed the vertical scroll bar not been take in consideration. Now the table will scroll and the header/footer will be aligned correctly.
Also I added a simple way to select a row.
Example: http://jsfiddle.net/0x3333/f0vfpvLm/4/
<div class="table-container"> <-- Header --> <div class="table-container-header"> <table class="table table-bordered"> <thead> <tr> <th>Header 1</th> ... <th>Header N</th> </tr> </thead> </table> </div> <-- Body --> <div class="table-container-body"> <table class="table table-bordered"> <-- You set the columns width here --> <colgroup> <col style="width: XXXpx;"></col> ... <col style="width: XXX%;"></col> </colgroup> <tbody> <tr> <td>Body 1</td> ... <td>Body N</td> </tr> </tbody> </table> </div> <!-- Optional --> <-- Footer --> <div class="table-container-footer"> <table class="table table-striped table-hover table-condensed table-bordered"> <tfoot> <tr> <th>Footer 1</th> ... <th>Footer N</th> </tr> </tfoot> </table> </div> </div>
p.fixed-table-scroll-inner {
width: 100%;
height: 200px;
}
div.fixed-table-scroll-outer {
top: 0;
left: 0;
visibility: hidden;
width: 200px;
height: 150px;
overflow: hidden;
}
.table-container {
border: 1px solid #ddd;
border-radius: 5px;
margin: 10px;
overflow: hidden;
}
.table-container-header {
overflow: hidden;
width: 100%;
}
.table-container-body {
height: 154px;
overflow: auto;
width: 100%;
}
.table-container-footer {
overflow: hidden;
width: 100%;
}
.table-container table {
margin-bottom: 0px;
table-layout: fixed;
}
.table-container table td,
.table-container table th {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.table-bordered {
border: 0px;
}
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td {
border-bottom-width: 2px;
}
.table-bordered > tfoot > tr > th,
.table-bordered > tfoot > tr > td {
border-top-width: 2px;
}
.table-bordered > tfoot > tr > th,
.table-bordered > tfoot > tr > td {
border-bottom-width: 0px;
}
/*Left*/
.table-bordered > thead > tr > th:first-child,
.table-bordered > tbody > tr > th:first-child,
.table-bordered > tfoot > tr > th:first-child,
.table-bordered > thead > tr > td:first-child,
.table-bordered > tbody > tr > td:first-child,
.table-bordered > tfoot > tr > td:first-child {
border-left-width: 0px;
}
/*Right*/
.table-bordered > thead > tr > th:last-child,
.table-bordered > tbody > tr > th:last-child,
.table-bordered > tfoot > tr > th:last-child,
.table-bordered > thead > tr > td:last-child,
.table-bordered > tbody > tr > td:last-child,
.table-bordered > tfoot > tr > td:last-child {
border-right-width: 0px;
}
/*Top*/
.table-bordered > thead > tr:first-child > th,
.table-bordered > thead > tr:first-child > td {
border-top-width: 0px;
}
/*Bottom*/
.table-bordered > tfoot > tr:last-child > th,
.table-bordered > tfoot > tr:last-child > td {
border-bottom-width: 0px;
}
<div class="table-container">
<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>
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);
redraw();