0

How do I create a simple scrollable table row with a frozen header without using any additional jQuery plugins?

I found some solutions which used jQuery plugins like fixedheadertable, chromatable and so on, but I just want to use the "pure" library in jQuery.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Jack
  • 377
  • 5
  • 19
  • [What have you tried?](http://www.whathaveyoutried.com) You will find you get better responses if you first make an attempt and then come here with more specific issues you are facing. – James Montagne Sep 19 '12 at 18:40
  • Sorry. i tried so many solutions these two days, plugins like fixedheadertable & chromatable would be the great solutions, but i prefer to use "pure" & simple jquery to archieve it. i will try again tomorrow, then i will post again. Thanks for your rreminder, because, i already have no idea which is the best. I will try to figure it out tomorrow and update my post. Thanks. – Jack Sep 19 '12 at 21:30

3 Answers3

0

Show/Hide Header Row at Screen Top - only jQ

Basically hide an empty table/tr shell with fixed position at the top of the body. Create a function to loop through the first row of the data table and capture the width and innerHTML. Invoke that function on pageload so it's ready. Capture how far from top of screen to top of your data table. When page scrolls past that point toggle show/hide the table. Also capture when window is resized to repopulate the fixed table/tr shell....

<script type="text/javascript">
var distance = 0, $window = $(window);
function resizeHdr(){
    $("#tblHoldHdr").css("width", $("#tblData").css("width"));
    var oTr=$("#trHoldHdr").html("");//short var for frozen header row
    $("#tblData tr:first").find("th").each(function(i){//loop through header to mimic
        oTr.append('<th style="width:'+$(this).css("width")+' !important">'+$(this).html()+'</th>');//copy content with forced width
    });
}
$(function(){
    distance=$('#tblData').offset().top;
    $("#tblHoldHdr").css({"margin-left":$("body").css("margin"),"margin-top":-parseInt($("body").css("margin"))+"px"});//position frozen hder
    resizeHdr();
});
$(window).scroll(function(){
    $("#tblHoldHdr").css("left", -$(this).scrollLeft());//frozen hdr pos fixed doesn't move w/ scrolling so this keeps it lined up (w/o "-" header slides twice as fast out to the right)
    if($window.scrollTop() >= distance){
        $("#tblHoldHdr").css("display","");// Hdr has reached the top
    }else{
        $("#tblHoldHdr").css("display","none");// Hdr below top
    }
});
$(window).resize(function(){
    resizeHdr();
});
</script>
<!-- At the top goes this is the frozen header table - populated by jQ on doc.ready() -->

<table style="display:none;position:fixed;" id="tblHoldHdr">
    <tr id="trHoldHdr"></tr>
</table>
…other html code…
<!-- This is the data output table wherever you need it on the page -->
<table id="tblData"><thead>
    <tr><th> Col 1</th><th>Col 2</th></tr>
    <tr><td> Data 1/1</td><td>Data 1/2</td></tr>
    <tr><td> Data 2/1</td><td>Data 2/2</td></tr>
</table>

I've borrowed from various people on how to capture scroll and window resizing. I originally had the fixed table/tr populated once and just apply the size, but Chrome worked and then it didn't. Someone else may have the magic juju to get that simpler method to work.

Community
  • 1
  • 1
gordon
  • 1,152
  • 1
  • 12
  • 18
0

Here a demo of scroll synchronization

https://jsfiddle.net/RaviMakwana/28fgaut5/

var div1 = document.getElementById("scrollDiv1");
var div2 = document.getElementById("scrollDiv2");
div2.addEventListener("scroll", function(){  
   div1.scrollLeft = this.scrollLeft;
})
<div id="scrollDiv1" style="height: 100px;overflow:hidden;">
   <div style="width:1000px;">
    Test 1 321321 131 313 1321 33 13
   </div>
</div>

<div id="scrollDiv2" style="height: 100px;overflow:scroll;">
   <div style="width:1000px;">
    Test 2 23232
   </div>
</div>
Ravi Makwana
  • 2,782
  • 1
  • 29
  • 41
0

ColdFusion template show/hide at top and resize fix

Here's a version you can cfinclude - only <cfset dataTblId=""> is required, but some other attributes are available. Saves HTML in the header <th>s.

<CFIF isDefined("variables.dataTblId") and !findNoCase("Mozilla/4.0", cgi.http_user_agent) and !findNoCase("compatible", cgi.http_user_agent)>
<cfparam name="variables.hdrTblHtmlAttr" default=""><!--- for old HTML attributes of the data table (e.g., cellspacing, cellpadding, align, etc.) --->
<cfif len(variables.hdrTblHtmlAttr)><!--- inserted table is defined inside single quotes, must have doublequote attribute values --->
    <cfset variables.hdrTblHtmlAttr=replace(variables.hdrTblHtmlAttr, "'", '"', "all")>
</cfif>
<cfparam name="variables.hdrTrClass" default="">
<cfparam name="variables.hdrTrStyle" default="">
<cfparam name="variables.hdrTdClass" default="">
<cfparam name="variables.hdrTdStyle" default="">
<cfparam name="variables.dirOfJq" default="/js/"><!--- should be relative, but /js should be in place --->
<cfparam name="variables.jQFile" default="jquery-3.2.1.min.js"><!--- in case new version is implemented (expect this code should still work but?....) --->
<cfoutput>
<script type="text/javascript" src="#variables.dirOfJq##variables.jQFile#"></script>
<script type="text/javascript">
var distance = 0, $window = $(window);
function resizeHdr(){
    $("##tblHoldHdr").css("width", $("###variables.dataTblId#").css("width"));
    var oTr=$("##trHoldHdr").html("");//short var for frozen header row, cleared out
    $("###variables.dataTblId# tr:first").find("th").each(function(i){//loop through header to mimic
        oTr.append('<th style="width:'+$(this).css("width")+' !important">'+$(this).html()+'</th>');//copy content with forced width
    });
}
$(function(){
    $("body").prepend(<!--- stuff frozen header table html into the page just inside/at top of <body> --->
    '<table class="'+$("###variables.dataTblId#").attr("class")+'" style="display:none;position:fixed;background-color:white;'+$("###variables.dataTblId#").attr("style")+'" id="tblHoldHdr" #variables.hdrTblHtmlAttr#>'+
        '<tr id="trHoldHdr" class="#variables.hdrTrClass#" style="#variables.hdrTrStyle#"></tr></table>'
    )
    distance=$('###variables.dataTblId#').offset().top;
    $("##tblHoldHdr").css({"margin-left":$("body").css("margin"),"margin-top":-parseInt($("body").css("margin"))+"px"});//position frozen hder
    resizeHdr();//populate for scroll w/o resize
});
</cfoutput>
$(window).scroll(function(){
    $("#tblHoldHdr").css("left", -$(this).scrollLeft());//frozen hdr pos fixed doesn't move w/ scrolling so this keeps it lined up (w/o "-" header slides twice as fast out to the right) 
    if($window.scrollTop() >= distance){
        $("#tblHoldHdr").css("display","");// Hdr has reached the top
    }else{
        $("#tblHoldHdr").css("display","none");// Hdr below top
    }
});
$(window).resize(function(){
    resizeHdr();
});
</script>
</CFIF>
Community
  • 1
  • 1
gordon
  • 1,152
  • 1
  • 12
  • 18