Saturday, May 16, 2009

Scrollable Table with fixed header and first column

From a long time ,I was searching for a script that can satisfy my need to have a scrollable table with fixed header and fixed First column,I tried many scripts but some of them were not compatible with the application I want to make(I was trying to make a calendar for aircraft activity in a flight management system with drag drop functionality.) and some script was not multi browser capable so I decided to write my own script using jquery.I am not a master in jquery but I know its basic use.
so I want to share this code with the one who want to create their own scrollable table with flexible content for the table.





<html>
<head>
<script type="text/javascript" src="http://jqueryui.com/latest/jquery-1.3.2.js"></script>
<script>
$(document).ready(function(){
fnAdjustTable();
});

fnAdjustTable=function(){

var colCount=$('#firstTr>td').length; //get total number of column

var m=0;
var n=0;
var brow='mozilla';
jQuery.each(jQuery.browser, function(i, val) {
if(val==true){

brow=i.toString();
}
});
$('.tableHeader').each(function(i){
if(m<colCount){

if(brow=='mozilla'){
$('#firstTd').css("width",$('.tableFirstCol').innerWidth());//for adjusting first td

$(this).css('width',$('#table_div td:eq('+m+')').innerWidth());//for assigning width to table Header div
}
else if(brow=='msie'){
$('#firstTd').css("width",$('.tableFirstCol').width());

$(this).css('width',$('#table_div td:eq('+m+')').width()-2);//In IE there is difference of 2 px
}
else if(brow=='safari'){
$('#firstTd').css("width",$('.tableFirstCol').width());

$(this).css('width',$('#table_div td:eq('+m+')').width());
}
else{
$('#firstTd').css("width",$('.tableFirstCol').width());

$(this).css('width',$('#table_div td:eq('+m+')').innerWidth());
}
}
m++;
});

$('.tableFirstCol').each(function(i){
if(brow=='mozilla'){
$(this).css('height',$('#table_div td:eq('+colCount*n+')').outerHeight());//for providing height using scrollable table column height
}else if(brow=='msie'){

$(this).css('height',$('#table_div td:eq('+colCount*n+')').innerHeight()-2);
}else{
$(this).css('height',$('#table_div td:eq('+colCount*n+')').height());
}
n++;
});



}

//function to support scrolling of title and first column
fnScroll=function(){

$('#divHeader').scrollLeft($('#table_div').scrollLeft());
$('#firstcol').scrollTop($('#table_div').scrollTop());


}

</script>
</head>
<body>
<table cellspacing="0" cellpadding="0" border="0" >
<tr>
<td id="firstTd">
</td>
<td>
<div id="divHeader" style="overflow:hidden;width:284px;">
<table cellspacing="0" cellpadding="0" border="1" >
<tr>
<td ><div class="tableHeader">Title1</div></td><td><div class="tableHeader">Title2</div></td><td><div class="tableHeader">Title3</div></td><td><div class="tableHeader">Title4</div></td><td><div class="tableHeader">Title5</div></td>
</tr>
</table>
</div>
</td>
</tr>
<tr>
<td valign="top">
<div id="firstcol" style="overflow: hidden;height:80px">
<table width="200px" cellspacing="0" cellpadding="0" border="1" >
<tr>
<td class="tableFirstCol">First Col row1 </td>
</tr>
<tr>
<td class="tableFirstCol">First Col row2</td>
</tr>
<tr>
<td class="tableFirstCol">First Col row3</td>
</tr>
<tr>
<td class="tableFirstCol">First Col row4</td>
</tr>
<tr>
<td class="tableFirstCol">First Col row5</td>
</tr>
<tr>
<td class="tableFirstCol">First Col row6</td>
</tr>
<tr>
<td class="tableFirstCol">First Col row7</td>
</tr>
<tr>
<td class="tableFirstCol">First Col row8</td>
</tr>
<tr>
<td class="tableFirstCol">First Col row9</td>
</tr>
</table>
</div>
</td>
<td valign="top">
<div id="table_div" style="overflow: scroll;width:300px;height:100px;position:relative" onscroll="fnScroll()" >
<table width="500px" cellspacing="0" cellpadding="0" border="1" >
<tr id='firstTr'>
<td>Row1Col1</td><td>Row1Col2</td><td>Row1Col3</td><td>Row1Col4</td><td>Row1Col5</td>
</tr>
<tr>
<td>Row2Col1</td><td>Row2Col2</td><td>Row2Col3</td><td>Row2Col4</td><td>Row3Col5</td>
</tr>
<tr>
<td>Row3Col1</td><td>Row3Col2</td><td>Row3Col3</td><td>Row3Col4</td><td>Row3Col5</td>
</tr>
<tr>
<td>Row4Col1</td><td>Row4Col2</td><td>Row4Col3</td><td>Row4Col4</td><td>Row4Col5</td>
</tr>
<tr>
<td>Row5Col1</td><td>Row5Col2</td><td>Row5Col3</td><td>Row5ol4</td><td>Row5Col5</td>
</tr>
<tr>
<td>Row6Col1</td><td>Row6Col2</td><td>Row6Col3</td><td>Row6Col4</td><td>Row6Col5</td>
</tr>
<tr>
<td>Row7Col1</td><td>Row7Col2</td><td>Row7Col3</td><td>Row7Col4</td><td>Row7Col5</td>
</tr>
<tr>
<td>Row8Col1</td><td>Row8Col2</td><td>Row8Col3</td><td>Row8Col4</td><td>Row8Col5</td>
</tr>
<tr>
<td>Row9Col1</td><td>Row9Col2</td><td>Row9Col3</td><td>Row9Col4</td><td>Row9Col5</td>
</tr>
</table>
</div>
</tr>
</table>
</body>
</html>



I hope this will be helpful for some one

15 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Good one pavan,Just go in settings ,and in permissions ,add me in authors list so i can also post in ur blog

    ReplyDelete
  3. Great work, been looking for a solution to this for a long time...

    If it helps, I've posted a working example at:
    http://acatalept.com/common/test/fixed-table.html

    And formatted source code (to make it a little easier to read) at:
    http://snipt.org/loz

    ReplyDelete
  4. This was great, but I wanted code that would adjust EITHER the header cell width/height, OR the table cell width/height.

    after 4 days of dinking around, I determined that to change the width of a cell in the data table, you have to first change the width of the table itself by the same amount.
    Could be that there's a better way to do this, but this is what I came up with:
    [in my example, I changed the way the selector for the data cells works, and I added row and column classes to the data cells, but I don't think this was strictly necessary]

    the changed code looks like:
    - um, looks like I can't cut and paste into this textbox??

    well, anyways, basically you check if the header or data cell is larger, and adjust acccordingly. If it's the data cell you're widening, then widen the table by the same amount.

    ReplyDelete
  5. Seems like the table does not scroll correctly or even align the columns vertically if you have spanned columns in the header. Any idea?

    ReplyDelete
  6. for spanned columns ,I think if u give same colspan to all table in use than it should work ,not pretty sure.

    ReplyDelete
  7. I've cleaned this up for you at put it in jsbin for a demo

    http://jsbin.com/owuva4

    ReplyDelete
  8. great script, but when a column is empty it goes wrong in the header. For example if you remove all the values of column 4 in your example, the header of column 4 is not visible anymore.

    I'm not familiar with javascript. I think it's not difficult to take the maximum width of the header or the maximum width of the column as the column width. Anybody that can help me?

    ReplyDelete
  9. Very nice. The horizontal scrolling has some problems when changing text direction (i.e putting dir="rtl" in the body tag ). Any idea how to solve this ?

    ReplyDelete
  10. Hello All,

    I need one requirement in this demo. When Cell "Row1Col2" inner-HTML increase at that time Cell width automatically increase, I need at the same time increase respected column header
    (Title2) width increase same as Cell of "Row1Col2".

    Thanks

    ReplyDelete
  11. I need one requirement in this demo.i want sorting every column.

    ReplyDelete