how to freeze table header using javascript - javascript

I have table with 200 rows. The first row has headings(th tag). While i am scrolling down the heading is to be fixed and visible to all rows. Any help?
Thank You

Easiest answer, check this out -> http://www.imaputz.com/cssStuff/bigFourVersion.html
One caveat: Does not work for IE 7-9 (Does work for 6 and 10). If you need a solution for 7-9, try jQuery Scrollable Table Plugin. You can even set it up to only use the JS for IE versions 7-9 by placing the javascript call for it inside IE if comments. Then you'd know anyone using a better browser would be using pure CSS (faster) and you'd have a solution for those using crap ... i mean IE 7,8, or 9.
It basically has to do with the CSS. One key is setting table-body to display: block. Another issue is going to be in dealing with fixed widths. Just check it out. It's REALLY easy to copy that example.
Really not much more I can say! This example is PURE CSS, no JS!
jsFiddle
CSS
/* define height and width of scrollable area. Add 16px to width for scrollbar */
div.tableContainer {
clear: both;
border: 1px solid #963;
height: 285px;
overflow: auto;
width: 756px
}
/* Reset overflow value to hidden for all non-IE browsers. */
html>body div.tableContainer {
overflow: hidden;
width: 756px
}
/* define width of table. IE browsers only */
div.tableContainer table {
float: left;
width: 740px
}
/* define width of table. Add 16px to width for scrollbar. */
/* All other non-IE browsers. */
html>body div.tableContainer table {
width: 756px
}
/* set table header to a fixed position. WinIE 6.x only */
/* In WinIE 6.x, any element with a position property set to relative and is a child of */
/* an element that has an overflow property set, the relative value translates into fixed. */
/* Ex: parent element DIV with a class of tableContainer has an overflow property set to auto */
thead.fixedHeader tr {
position: relative
}
/* set THEAD element to have block level attributes. All other non-IE browsers */
/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
html>body thead.fixedHeader tr {
display: block
}
/* make the TH elements pretty */
thead.fixedHeader th {
background: #C96;
border-left: 1px solid #EB8;
border-right: 1px solid #B74;
border-top: 1px solid #EB8;
font-weight: normal;
padding: 4px 3px;
text-align: left
}
/* make the A elements pretty. makes for nice clickable headers */
thead.fixedHeader a, thead.fixedHeader a:link, thead.fixedHeader a:visited {
color: #FFF;
display: block;
text-decoration: none;
width: 100%
}
/* make the A elements pretty. makes for nice clickable headers */
/* WARNING: swapping the background on hover may cause problems in WinIE 6.x */
thead.fixedHeader a:hover {
color: #FFF;
display: block;
text-decoration: underline;
width: 100%
}
/* define the table content to be scrollable */
/* set TBODY element to have block level attributes. All other non-IE browsers */
/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
/* induced side effect is that child TDs no longer accept width: auto */
html>body tbody.scrollContent {
display: block;
height: 262px;
overflow: auto;
width: 100%
}
/* make TD elements pretty. Provide alternating classes for striping the table */
/* http://www.alistapart.com/articles/zebratables/ */
tbody.scrollContent td, tbody.scrollContent tr.normalRow td {
background: #FFF;
border-bottom: none;
border-left: none;
border-right: 1px solid #CCC;
border-top: 1px solid #DDD;
padding: 2px 3px 3px 4px
}
tbody.scrollContent tr.alternateRow td {
background: #EEE;
border-bottom: none;
border-left: none;
border-right: 1px solid #CCC;
border-top: 1px solid #DDD;
padding: 2px 3px 3px 4px
}
/* define width of TH elements: 1st, 2nd, and 3rd respectively. */
/* Add 16px to last TH for scrollbar padding. All other non-IE browsers. */
/* http://www.w3.org/TR/REC-CSS2/selector.html#adjacent-selectors */
html>body thead.fixedHeader th {
width: 200px
}
html>body thead.fixedHeader th + th {
width: 240px
}
html>body thead.fixedHeader th + th + th {
width: 316px
}
/* define width of TD elements: 1st, 2nd, and 3rd respectively. */
/* All other non-IE browsers. */
/* http://www.w3.org/TR/REC-CSS2/selector.html#adjacent-selectors */
html>body tbody.scrollContent td {
width: 200px
}
html>body tbody.scrollContent td + td {
width: 240px
}
html>body tbody.scrollContent td + td + td {
width: 300px
}
HTML
<div id="tableContainer" class="tableContainer">
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="scrollTable">
<thead class="fixedHeader">
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
<tbody class="scrollContent">
<tr>
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr>
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
<tr>
<td>Even More Cell Content 1</td>
<td>Even More Cell Content 2</td>
<td>Even More Cell Content 3</td>
</tr>
<tr>
<td>And Repeat 1</td>
<td>And Repeat 2</td>
<td>And Repeat 3</td>
</tr>
...
...
...
<tr>
<td>End of Cell Content 1</td>
<td>End of Cell Content 2</td>
<td>End of Cell Content 3</td>
</tr>
</tbody>
</table>
</div>

Related

Expand last table column to fill container

How do you expand the last column of a table to fill the parent container without specifying a width for the container?
In this jsfiddle, I want the last column of the green table to fill the blue container. The width of the container should only be determined by its text.
.container{
background-color: #003388;
color: white;
display: inline-block;
}
table {
background-color: #008833;
color: white;
width:auto;
}
table tr td:last-child {
/* width:100%; */
}
Setting the width of the last td fills the entire page.
One possible approach is given below. It uses...
width: 100% rule (instead of width: auto) to make table fill the container
width: 1px; white-space: nowrap; combo trick to make all the columns define their width based on content width; without that rule it seems there's no simple way to override default behaviour of table-layout: auto sharing the whole width between columns equally.
max-width: 1px for the last column to ensure that inline-block container is not extended when that column grows, and text is wrapped instead
.container{
background-color: #003388;
color: white;
display: inline-block;
}
table {
background-color: #008833;
color: white;
width: 100%;
}
table td:not(:last-child) {
width: 1px;
white-space: nowrap;
}
table td:last-child {
max-width: 1px;
}
<div class="container">
long text long text long text long text long text long text
<table>
<tr>
<th>Product</th>
<th>Cardinality</th>
<th>Price per item</th>
</tr>
<tr>
<td>Apple</td>
<td>5</td>
<td>$2</td>
</tr>
<tr>
<td>Pear</td>
<td>3</td>
<td>$3</td>
</tr>
<tr>
<td>Sausage</td>
<td>10</td>
<td>$0.5</td>
</tr>
<tr>
<td>Pineapple</td>
<td>2</td>
<td>$8</td>
</tr>
<tr>
<td>Tomato</td>
<td>5</td>
<td>$1</td>
</tr>
<tr>
<td>Lightsaber</td>
<td>2</td>
<td>$99 999 999999999 99999999 99999999</td>
</tr>
</table>
</div>
Use fractional units fr to automatically take up the fraction you desire

Table header stay fixed when search element inside table

I need some help! I use flask to create a website with data table, I tried many different methods but I don't manage to fix the table head and when I search the table head collapsed also. How can I solve it in my code please?
my table
HTML:
<div>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for Country">
</div>
<table id="myTable">
<thead>
<tr>
<th>Country</th>
<th>Total Cases</th>
<th>Today Cases</th>
<th>Total Deaths</td>
<th>Today Deaths</th>
<td>Total Recovered</td>
<td>Active</td>
<td>Critical</td>
<td>Cases Per One Million</td>
<td>Deaths Per One Million</td>
<td>Total Tests</td>
<td>Tests Per One Million</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
CSS:
#myTable {
border-collapse: collapse;
/* Collapse borders */
width: 100%;
/* Full-width */
border: 1px solid #ddd;
/* Add a grey border */
font-size: 18px;
/* Increase font-size */
}
#myTable th,
#myTable td {
text-align: left;
/* Left-align text */
padding: 12px;
/* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
JavaScript:
$(document).ready(function(){
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});

.outerHeight & .outerWidth grows exponentially, when setting table cell height & width

Another web developer wanted to freeze the left-most column and allow scrolling of the table. He found this code and implemented into his client's site. The code does its job and works as expected.
However he added some #media queries to make the table a bit more responsive. When doing so it screwed up the table. It left the left column to not be aligned with the rest of the table.
#media screen and (max-width: 699px) and (min-width: 520px) {
.exportTable th{
min-width: 170px !important;
}
.exportTable td{
min-width:170px !important;
max-width:170px !important;
}
}
So I added the function call inside a window.resize().
$(document).ready(function () {
app_handle_listing_horisontal_scroll($('#exportTable-listing'));
app_handle_listing_horisontal_scroll($('#exportTable-listing2'));
$(window).resize(function() {
app_handle_listing_horisontal_scroll($('#exportTable-listing'));
app_handle_listing_horisontal_scroll($('#exportTable-listing2'));
});
});
The code was called upon resize of the window however, the outerHeight and outerWidth grew exponentially, causing a serious issue.
The issue happens when you set the height:
$(this).css('height', current_row_height);
and the width/margin:
$(this).css('position','absolute')
.css('margin-left','-'+table_collumns_margin[index]+'px')
.css('width',table_collumns_width[index])
Here is a fiddle.
Simply grab the window and resize back and forth, the table cell's height/width will exponentially grow, causing a serious issue.
This fiddle demonstrates how when you hit the #media queries that the left column will be misaligned. (it's important when viewing this fiddle to get the #media query to be hit.)
How can I resolve these issues?
In my opinion, adding javascript to the equation makes it overly complex. I believe what you want can be accomplished with CSS alone.
How this works, if the browser has a max-width of 500px, then remove the sticky column. If not, show the sticky column.
Unless you need to support browsers older than IE 9, then try this on for size:
https://jsfiddle.net/BmLpV/284/
CSS:
.zui-table {
border: none;
border-right: solid 1px #DDEFEF;
border-collapse: separate;
border-spacing: 0;
font: normal 13px Arial, sans-serif;
}
.zui-table thead th {
background-color: #DDEFEF;
border: none;
color: #336B6B;
padding: 10px;
text-align: left;
text-shadow: 1px 1px 1px #fff;
white-space: nowrap;
}
.zui-table tbody td {
border-bottom: solid 1px #DDEFEF;
color: #333;
padding: 10px;
text-shadow: 1px 1px 1px #fff;
white-space: nowrap;
}
.zui-wrapper {
position: relative;
}
.zui-scroller {
margin-left: 141px;
overflow-x: scroll;
overflow-y: visible;
padding-bottom: 5px;
width: 300px;
}
.zui-table .zui-sticky-col {
border-left: solid 1px #DDEFEF;
border-right: solid 1px #DDEFEF;
left: 0;
position: absolute;
top: auto;
width: 120px;
}
#media (max-width: 500px) {
.zui-table .zui-sticky-col {
border-left: solid 1px #DDEFEF;
border-right: solid 1px #DDEFEF;
position: relative;
top: auto;
width: auto;
}
.zui-scroller {
margin-left: 0;
}
}
HTML:
<div class="zui-wrapper">
<div class="zui-scroller">
<table class="zui-table">
<thead>
<tr>
<th class="zui-sticky-col">Name</th>
<th>Number</th>
<th>Position</th>
<th>Height</th>
<th>Born</th>
<th>Salary</th>
<th>Prior to NBA/Country</th>
</tr>
</thead>
<tbody>
<tr>
<td class="zui-sticky-col">DeMarcus Cousins</td>
<td>15</td>
<td>C</td>
<td>6'11"</td>
<td>08-13-1990</td>
<td>$4,917,000</td>
<td>Kentucky/USA</td>
</tr>
<tr>
<td class="zui-sticky-col">Isaiah Thomas</td>
<td>22</td>
<td>PG</td>
<td>5'9"</td>
<td>02-07-1989</td>
<td>$473,604</td>
<td>Washington/USA</td>
</tr>
<tr>
<td class="zui-sticky-col">Ben McLemore</td>
<td>16</td>
<td>SG</td>
<td>6'5"</td>
<td>02-11-1993</td>
<td>$2,895,960</td>
<td>Kansas/USA</td>
</tr>
<tr>
<td class="zui-sticky-col">Marcus Thornton</td>
<td>23</td>
<td>SG</td>
<td>6'4"</td>
<td>05-05-1987</td>
<td>$7,000,000</td>
<td>Louisiana State/USA</td>
</tr>
<tr>
<td class="zui-sticky-col">Jason Thompson</td>
<td>34</td>
<td>PF</td>
<td>6'11"</td>
<td>06-21-1986</td>
<td>$3,001,000</td>
<td>Rider/USA</td>
</tr>
</tbody>
</table>
</div>
</div>
Edit: To support dynamic heights, you could do something like this:
$(function(){
$('.zui-table tr').each(function(i, row) {
var height = $('.zui-sticky-col').eq(i).outerHeight() - $('.zui-sticky-col').eq(i).height();
$('.zui-sticky-col').eq(i).height($(row).height() - height);
});
})
For better performance, you could only access the element once:
$(function(){
$('.zui-table tr').each(function(i, row) {
var el = $('.zui-sticky-col').eq(i);
var height = el.outerHeight() - el.height();
el.height($(row).height() - height);
});
})
https://jsfiddle.net/BmLpV/289/

How do I make a <tr> behave as a fixed topbar?

I have a table that displays some information with the first row being headers for the respective information.
On scrolling, let's say 100px from the top of the page, i'd like the header row to stay fixed at the top of the visible screen so that as you scroll down the table you can still see the headers.
I've tried:
$(window).scroll(function(){
if( $(window).pageYOffset > 100 ){
$("#resultTableHeader").css('position', 'fixed');
$("#resultTableHeader").css('top', '70px');
$("#resultTableHeader").css('z-index', '2');
}
});
but it doesn't seem to do anything.
Even if it did, however, make the header row fixed, If one column expanded the header row column, then pulling it out of the flow would make that column not be expanded anymore.
Is there a way to do this?
EDIT (more info):
I can guarantee that the whole page will be just the table so staying at the top of the screen for any Y co-ord past 100px would be acceptable.
When I say fixed I mean that the header row will stay pinned to the top of the VISIBLE window as you scroll down along the table.
Fixed table header with pure html and css
html, body{
margin:0;
padding:0;
height:100%;
}
section {
position: relative;
border: 1px solid #000;
padding-top: 37px;
background: #500;
}
section.positioned {
position: absolute;
top:100px;
left:100px;
width:800px;
box-shadow: 0 0 15px #333;
}
.container {
overflow-y: auto;
height: 200px;
}
table {
border-spacing: 0;
width:100%;
}
td + td {
border-left:1px solid #eee;
}
td, th {
border-bottom:1px solid #eee;
background: #ddd;
color: #000;
padding: 10px 25px;
}
th {
height: 0;
line-height: 0;
padding-top: 0;
padding-bottom: 0;
color: transparent;
border: none;
white-space: nowrap;
}
th div{
position: absolute;
background: transparent;
color: #fff;
padding: 9px 25px;
top: 0;
margin-left: -25px;
line-height: normal;
border-left: 1px solid #800;
}
th:first-child div{
border: none;
}
<section class="">
<div class="container">
<table>
<thead>
<tr class="header">
<th>
Table attribute name
<div>Table attribute name</div>
</th>
<th>
Value
<div>Value</div>
</th>
<th>
Description
<div>Description</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>align</td>
<td>left, center, right</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
</tr>
<tr>
<td>bgcolor</td>
<td>rgb(x,x,x), #xxxxxx, colorname</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
</tr>
<tr>
<td>border</td>
<td>1,""</td>
<td>Specifies whether the table cells should have borders or not</td>
</tr>
<tr>
<td>cellpadding</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
</tr>
<tr>
<td>cellspacing</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between cells</td>
</tr>
<tr>
<td>frame</td>
<td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
<td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
</tr>
<tr>
<td>rules</td>
<td>none, groups, rows, cols, all</td>
<td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
</tr>
<tr>
<td>summary</td>
<td>text</td>
<td>Not supported in HTML5. Specifies a summary of the content of a table</td>
</tr>
<tr>
<td>width</td>
<td>pixels, %</td>
<td>Not supported in HTML5. Specifies the width of a table</td>
</tr>
</tbody>
</table>
</div>
</section>
This is a common problem when using table elements. Most libraries use two tables to fix this. The first table only contains the th elements and the second table has all tr elements.
Check jqgrid for example.

Trying to make fixed table headers with horizontal scroll bar. How to set overflow: auto, but keep margins transparent?

I am trying to make a table with fixed headers and horizontal scrolling functionality, but to do so I need to make the "section"'s top margin transparent in what I have here:
html, body {
margin:0;
padding:0;
height:100%;
}
.section {
position: relative;
border: 1px solid #000;
padding-top: 37px;
background: #500;
margin-top: 37px;
}
.container {
margin-top: -37px;
overflow-y: auto;
height: 200px;
}
table {
border-spacing: 0;
width:100%;
}
td + td {
border-left:1px solid #eee;
}
td, th {
border-bottom:1px solid #eee;
background: #ddd;
color: #000;
padding: 10px 25px;
}
th {
height: 0;
line-height: 0;
padding-top: 0;
padding-bottom: 0;
color: transparent;
border: none;
white-space: nowrap;
}
th div {
position: absolute;
margin-top:-37px;
background: transparent;
color: #fff;
padding: 9px 25px;
top: 0;
margin-left: -25px;
line-height: normal;
border-left: 1px solid #800;
}
th:first-child div {
border: none;
}
<div class="section">
<div class="container">
<table>
<thead>
<tr class="header">
<th>Table attribute name
<div>Table attribute name</div>
</th>
<th>Value
<div>Value</div>
</th>
<th>Description
<div>Description</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>align</td>
<td>left, center, right</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
</tr>
<tr>
<td>bgcolor</td>
<td>rgb(x,x,x), #xxxxxx, colorname</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
</tr>
<tr>
<td>border</td>
<td>1,""</td>
<td>Specifies whether the table cells should have borders or not</td>
</tr>
<tr>
<td>cellpadding</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
</tr>
<tr>
<td>cellspacing</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between cells</td>
</tr>
<tr>
<td>frame</td>
<td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
<td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
</tr>
<tr>
<td>rules</td>
<td>none, groups, rows, cols, all</td>
<td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
</tr>
<tr>
<td>summary</td>
<td>text</td>
<td>Not supported in HTML5. Specifies a summary of the content of a table</td>
</tr>
<tr>
<td>width</td>
<td>pixels, %</td>
<td>Not supported in HTML5. Specifies the width of a table</td>
</tr>
</tbody>
</table>
</div>
</div>
https://jsfiddle.net/byB9d/6212/
Thanks in advance to anyone with suggestions!
P.S. I would like a pure css solution, please!
I decided to remove most of your css to (hopefully) give a clearer answer to this question. I did however not change any of your html.
Fiddle with code
x-scrolling and width
This method relies on using the "table" as a container for "thead" and "tbody". "table" will determine the scrolling along the x-axis. Therefore it has "overflow-x: auto". This way the "thead" can stay positioned above the "tbody" while scrolling the table. (will be explained later)
This element also determines the width the table will take up on your webpage.
In order for the content to scroll horizontally we have to make sure the total width of "tbody" and "thead" is longer than the width of "table".
Finally you should also add the same width to your cells so the headers appear properly above your data. I did this by applying a width to "tr th:nth-child(1), tr td:nth-child(1)" (for each column).
y-scrolling and height
We want the "thead" to stay positioned on top of our table. Even when we scroll. Therefore we simply convert it to a block element.
The "tbody" is another story. we want to be able to vertically scroll it. Therefore we add "overflow-y: auto" and also set a fixed height for the element (otherwise it will just drop down and not scroll).
The total height of the table will be the height of "thead" and "tbody". The "table will adapt its size to fit it."
The CSS (html is the same as it is in the question post)
td, th {
border-bottom:1px solid #eee;
background: #ddd;
color: #000;
padding: 10px 25px;
}
th div{display: none;} /*why is this html even here!?!?*/
table {
display: block;
position: relative;
border: 1px solid #000;
width: 75%;
border-spacing: 0;
margin: auto;
overflow-x: auto;
}
thead{
display: block;
position: relative;
width: 700px; /*total width of columns*/
}
tbody{
display: block;
position: relative;
height: 250px;
overflow-y: auto;
width: 700px; /*total width of columns.*/
}
tr th:nth-child(1), tr td:nth-child(1){
width: 100px;
}
tr th:nth-child(2), tr td:nth-child(2){
width: 150px;
}
tr th:nth-child(3), tr td:nth-child(3){
width: 450px;
}
PS: I assume this is what you were trying to ask.

Categories