Edit 5:
- Added configurable fixed Rows and Columns.
- Fixed column width and height issues
- Reduced usage of complex selectors
Usage:
$('#cTable').cTable({
width: 1300,
height: 500,
fCols: 2,
fRows: 2
});
DEMO: http://jsfiddle.net/rCuPf/7/embedded/result/ (updated demo)
Edit 4: Updated for colSpan on column 1. Demo: http://jsfiddle.net/skram/rKjk3/26/
Edit 3: Did some cleanup and some fixes: http://jsfiddle.net/rKjk3/22 Tested in IE9, FF and Chrome. (I don't have latest IE to test it now)
Edit 2: Fix for IE: http://jsfiddle.net/rKjk3/15/embedded/result/ (See latest above)
Edit 1: Fix for resize window http://jsfiddle.net/rKjk3/11/ (See latest above)
- Added window.resize event handler to set the width of the
rightContainer
so the width of actual table will be increased as you resize.
- Removed fixed width on
SBWrapper
so that it can fully utilize the available space inside the container.
I have created 2 demo for your requirement.
Sample to show how the rendered html will look like with a simple markup structure. This will allow you to look at the structure that is being rendered and how it is working :)
DEMO: http://jsfiddle.net/GmJ22/7/
Actual demo with the markup that you have posted. The code is just a rough version and may require some cleanup. Right now you can configure the width and height of the table. I am posting it so that you can take a look and give me some feedback.
DEMO: http://jsfiddle.net/rKjk3/10/embedded/result/ (see below fixed versions)
Full code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<HTML>
<HEAD>
<TITLE>big scrolling table example</TITLE>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$(function() {
$.fn.cTable = function(o) {
this.wrap('<div class="cTContainer" />');
this.wrap('<div class="relativeContainer" />');
//Update below template as how you have it in orig table
var origTableTmpl = '<table border="1" cellspacing="1" cellpadding="0" align="center" width="95%" ></table>';
//get row 1 and clone it for creating sub tables
var row1 = this.find('tr').slice(0, o.fRows).clone();
var r1c1ColSpan = 0;
for (var i = 0; i < o.fCols; i++ ) {
r1c1ColSpan += this[0].rows[0].cells[i].colSpan;
}
//create table with just r1c1 which is fixed for both scrolls
var tr1c1 = $(origTableTmpl);
row1.each(function () {
var tdct = 0;
$(this).find('td').filter( function () {
tdct += this.colSpan;
return tdct > r1c1ColSpan;
}).remove();
});
row1.appendTo(tr1c1);
tr1c1.wrap('<div class="fixedTB" />');
tr1c1.parent().prependTo(this.closest('.relativeContainer'));
//create a table with just c1
var c1= this.clone().prop({'id': ''});
c1.find('tr').slice(0, o.fRows).remove();
c1.find('tr').each(function (idx) {
var c = 0;
$(this).find('td').filter(function () {
c += this.colSpan;
return c > r1c1ColSpan;
}).remove();
});
var prependRow = row1.first().clone();
prependRow.find('td').empty();
c1.prepend(prependRow).wrap('<div class="leftSBWrapper" />')
c1.parent().wrap('<div class="leftContainer" />');
c1.closest('.leftContainer').insertAfter('.fixedTB');
//create table with just row 1 without col 1
var r1 = $(origTableTmpl);
row1 = this.find('tr').slice(0, o.fRows).clone();
row1.each(function () {
var tds = $(this).find('td'), tdct = 0;
tds.filter (function () {
tdct += this.colSpan;
return tdct <= r1c1ColSpan;
}).remove();
});
row1.appendTo(r1);
r1.wrap('<div class="topSBWrapper" />')
r1.parent().wrap('<div class="rightContainer" />')
r1.closest('.rightContainer').appendTo('.relativeContainer');
$('.relativeContainer').css({'width': 'auto', 'height': o.height});
this.wrap('<div class="SBWrapper"> /')
this.parent().appendTo('.rightContainer');
this.prop({'width': o.width});
var tw = 0;
//set width and height of rendered tables
for (var i = 0; i < o.fCols; i++) {
tw += $(this[0].rows[0].cells[i]).outerWidth(true);
}
tr1c1.width(tw);
c1.width(tw);
$('.rightContainer').css('left', tr1c1.outerWidth(true));
for (var i = 0; i < o.fRows; i++) {
var tr1c1Ht = $(c1[0].rows[i]).outerHeight(true);
var thisHt = $(this[0].rows[i]).outerHeight(true);
var finHt = (tr1c1Ht > thisHt)?tr1c1Ht:thisHt;
$(tr1c1[0].rows[i]).height(finHt);
$(r1[0].rows[i]).height(finHt);
}
$('.leftContainer').css({'top': tr1c1.outerHeight(true), 'width': tr1c1.outerWidth(true)});
var rtw = $('.relativeContainer').width() - tw;
$('.rightContainer').css({'width' : rtw, 'height': o.height, 'max-width': o.width - tw});
var trs = this.find('tr');
trs.slice(1, o.fRows).remove();
trs.slice(0, 1).find('td').empty();
trs.each(function () {
var c = 0;
$(this).find('td').filter(function () {
c += this.colSpan;
return c <= r1c1ColSpan;
}).remove();
});
r1.width(this.outerWidth(true));
for (var i = 1; i < c1[0].rows.length; i++) {
var c1Ht = $(c1[0].rows[i]).outerHeight(true);
var thisHt = $(this[0].rows[i]).outerHeight(true);
var finHt = (c1Ht > thisHt)?c1Ht:thisHt;
$(c1[0].rows[i]).height(finHt);
$(this[0].rows[i]).height(finHt);
}
$('.SBWrapper').css({'height': $('.relativeContainer').height() - $('.topSBWrapper').height()});
$('.SBWrapper').scroll(function () {
var rc = $(this).closest('.relativeContainer');
var lfW = rc.find('.leftSBWrapper');
var tpW = rc.find('.topSBWrapper');
lfW.css('top', ($(this).scrollTop()*-1));
tpW.css('left', ($(this).scrollLeft()*-1));
});
$(window).resize(function () {
$('.rightContainer').width(function () {
return $(this).closest('.relativeContainer').outerWidth() - $(this).siblings('.leftContainer').outerWidth();
});
});
}
$('#cTable').cTable({
width: 1300,
height: 500,
fCols: 2,
fRows: 2
});
});
</script>
<style>
.cTContainer { overflow: hidden; padding: 2px; }
.cTContainer table { table-layout: fixed; }
.relativeContainer { position: relative; overflow: hidden;}
.fixedTB { position: absolute; z-index: 11; }
.leftContainer { position: absolute; overflow: hidden; }
.rightContainer { position: absolute; overflow: hidden; }
.leftSBWrapper { position: relative; z-index: 10; }
.topSBWrapper { position: relative; z-index: 10; width: 100%; }
.SBWrapper { width: 100%; overflow: auto; }
td { background-color: white; overflow: hidden; padding: 1px; }
</style>
</HEAD>
<BODY>
<form name="MyForm" method="POST" action="">
<table border="1" width="100%" cellspacing="1" cellpadding="0" align="center">
<tr>
<td width="35%" align="left">header junk left</td>
<td >- HEADER JUNK MIDDLE -</td>
<td width="35%" align="right">header junk right</td>
</tr>
</table>
<br />
<table border="0" width="95%" cellspacing="1" cellpadding="0" align="center">
<tr>
<td width="60%" align="left">header junk left</td>
<td width="40%" align="right">check it out! <input type="checkbox" onchange="alert('your javascript here');" value="Y" name="checkitout"></td>
</tr>
</table>
<!-- big table here!!--><!-- big table here!!--><!-- big table here!!--><!-- big table here!!-->
<table border="1" width="95%" cellspacing="1" cellpadding="0" align="center" id="cTable" >
<tr>
<td width="5%" colspan="3">fixed can be long<br>or short</td>
<td width="9%" colspan="4">scroll A</td>
<td width="7%" colspan="2">scroll B</td>
<td width="3%">scroll C</td>
<td width="9%" colspan="4">scroll D</td>
<td width="7%" colspan="2">scroll E</td>
<td width="3%">scroll F</td>
<td width="9%" colspan="4">scroll G</td>
<td width="7%" colspan="2">scroll H</td>
<td width="3%">scroll I</td>
<td width="9%" colspan="4">scroll J</td>
<td width="7%" colspan="2">scroll K</td>
<td width="3%">scroll L</td>
<td width="9%" colspan="4">scroll M</td>
<td width="7%" colspan="2">scroll N</td>
<td width="3%">scroll O</td>
</tr>
<tr>
<td width="5%" colspan="3">2nd fixed header</td>
<td width="9%" colspan="4">scroll 2A</td>
<td width="7%">scroll 2B-1</td>
<td width="7%">scroll 2B-2 </td>
<td width="3%">scroll 2C</td>
<td width="9%" colspan="4">scroll 2D</td>
<td width="7%" colspan="2">scroll 2E</td>
<td width="3%">scroll 2F</td>
<td width="9%" colspan="4">scroll 2G</td>
<td width="7%" colspan="2">scroll 2H</td>
<td width="3%">scroll 2I</td>
<td width="9%" colspan="4">scroll 2J</td>
<td width="7%" colspan="2">scroll 2K</td>
<td width="3%">scroll 2L</td>
<td width="9%" colspan="4">scroll 2M</td>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…