|
First off I must say "WOW". This is some great code. But have you figured out yet how to modify this to freeze more than 1 column? It would be awesome to have the first 3-4 left columns to freeze as well. I've just spent about 3 weeks banging my head against the CSS wall trying to this and I'm just amazed at the speed. Thanks.
|
|
|
|
|
Here's the solution I used-
Nest a table in each of the first (fixed) cells with the columns you want.
You will need to use fixed width for these columns as the tables don't have any relation.
You'll also want to override the top / bottom border styles on these new columns so you don't get a double border.
|
|
|
|
|
This is what I want to do but I'm not sure how to implement what you suggest. I have 3 'title cells' to freeze on each row (the ones with class="reportRowHeader"). Here is the HTML section that is working now to freeze 1 cell on each row. Can you give me an example in this section to freeze the 3 columns? If you could give an example of how to do that with a dynamic number of columns (ie. all reportRowHeader columns) that completely solve my problem. Thanks.
<div id = "outerDiv">
<div id = "innerDiv">
<table class = "reportTable" cellspacing = "0">
<tr>
<td class = "reportCorner"> </td>
<td class = "reportCorner"> </td>
<td class = "reportCorner"> </td>
<td class = "reportColumnHeader">Albania</td>
<td class = "reportColumnHeader">Argentina</td>
<td class = "reportColumnHeader">Australia</td>
<td class = "reportColumnHeader">Denmark</td>
<td class = "reportColumnHeader">Finland</td>
<td class = "reportColumnHeader">Iceland</td>
<td class = "reportColumnHeader">Norway</td>
<td class = "reportColumnHeader">Sweden</td>
<td class = "reportColumnHeader">Number</td>
<td class = "reportColumnHeader">Percentage (of the whole sample)</td>
</tr>
<tr>
<td class = "reportRowHeader">Q.4 Legal Framework - What is the legal basis for the following?</td>
<td class = "reportRowHeader"> </td>
<td class = "reportRowHeader"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
</tr>
<tr>
<td class = "reportRowHeader"> </td>
<td class = "reportRowHeader">4.a The form and structure of the annual budget and related legislation</td>
<td class = "reportRowHeader"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
</tr>
<tr>
<td class = "reportRowHeader"> </td>
<td class = "reportRowHeader"> </td>
<td class = "reportRowHeader">Constitution</td>
<td class = "reportDataCell">1</td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell">1</td>
<td class = "reportDataCell">1</td>
<td class = "reportDataCell">1</td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell"> </td>
<td class = "reportDataCell">4</td>
<td class = "reportDataCell">50.0%</td>
</tr>
</table>
</div>
</div>
|
|
|
|
|
This solution is excellent! I have been trying to do this for some time. I was wondering about wrapping the text in the table cells, however. Before implementing your solution, my table looked very nice but was far less usable due to the non-fixed headers. Now my table works great but it contains some incredibly wide cells because the text is not wrapping.
I admit I am not a javascript expert by any means. Is there a relatively easy way to fix this and still maintain the fixed headers?
Thanks so much.
Andy
|
|
|
|
|
Hello all,
After some work, I have managed to get this script working in all of the major browsers, including IE, Firefox, Opera (buggy though), Konqueror, and Safari.
The only major difference from the original script is the table header MUST be enclosed in a <thead>, and the body must be in a <tbody> tag to work right.
var divContent = null;
var divHeaderRow = null;
var divHeaderColumn = null;
var divHeaderRowColumn = null;
var headerRowFirstColumn = null;
var x;
var y;
var horizontal = false;
var vertical = false;
// Copy table to top and to left
function CreateScrollHeader(content, scrollHorizontal, scrollVertical)
{
horizontal = scrollHorizontal;
vertical = scrollVertical;
divContent = content;
if(BrowserDetect.browser == "Konqueror") {
window.onload = CreateScrollHeaderActual;
} else {
CreateScrollHeaderActual();
}
}
function CreateScrollHeaderActual() {
if (divContent != null)
{
var widthCosmeticAdd = 0;
var heightCosmeticAdd = 0;
// browser specific cosmetic tweaks
if (BrowserDetect.browser == "Explorer") {
widthCosmeticAdd = 2;
heightCosmeticAdd = 2;
} else if(BrowserDetect.browser == "Opera" || BrowserDetect.browser == "Konqueror" || BrowserDetect.browser == "Safari") {
widthCosmeticAdd = 1;
heightCosmeticAdd = 1;
}
var originalTable = findFirstElementByType(divContent, 'table');
var headerRow = findFirstElementByType(originalTable, 'thead');
x = originalTable.offsetWidth;
y = originalTable.offsetHeight;
divHeaderRow = divContent.cloneNode(true);
if (horizontal)
{
divHeaderRow.style.height = (headerRow.offsetHeight + heightCosmeticAdd) + 'px';
divHeaderRow.style.overflow = "hidden";
divContent.parentNode.insertBefore(divHeaderRow, divContent);
originalTable.style.position = "absolute";
originalTable.style.top = "-" + (headerRow.offsetHeight + heightCosmeticAdd) + 'px';
y = y - headerRow.offsetHeight;
}
divHeaderRowColumn = divHeaderRow.cloneNode(true);
headerRowFirstColumn = findFirstElementByType(findFirstElementByType(headerRow,'tr'), 'th');
divHeaderColumn = divContent.cloneNode(true);
divContent.style.position = "relative";
if (vertical)
{
divContent.parentNode.insertBefore(divHeaderColumn, divContent);
divContent.style.left = headerRowFirstColumn.offsetWidth + 'px';
originalTable.style.position = "absolute";
originalTable.style.left = "-" + headerRowFirstColumn.offsetWidth + 'px';
}
else
{
divContent.style.left = "0px";
}
if (vertical)
{
divHeaderColumn.style.width = (headerRowFirstColumn.offsetWidth + widthCosmeticAdd) + 'px';
divHeaderColumn.style.overflow = "hidden";
divHeaderColumn.style.zIndex = "99";
divHeaderColumn.style.position = "absolute";
divHeaderColumn.style.left = "0px";
divHeaderColumn.style.top = (headerRow.offsetHeight + heightCosmeticAdd) + "px";
addScrollSynchronization(divHeaderColumn, divContent, "vertical");
x = x - headerRowFirstColumn.offsetWidth;
}
if (horizontal)
{
if (vertical)
{
divContent.parentNode.insertBefore(divHeaderRowColumn, divContent);
}
divHeaderRowColumn.style.position = "absolute";
divHeaderRowColumn.style.left = "0px";
divHeaderRowColumn.style.top = "0px";
divHeaderRowColumn.style.width = (headerRowFirstColumn.offsetWidth + widthCosmeticAdd) + 'px';
divHeaderRowColumn.overflow = "hidden";
divHeaderRowColumn.style.zIndex = "100";
divHeaderRowColumn.style.backgroundColor = "#ffffff";
}
if (horizontal)
{
addScrollSynchronization(divHeaderRow, divContent, "horizontal");
}
if (horizontal || vertical)
{
window.onresize = ResizeScrollArea;
ResizeScrollArea();
}
}
}
function findFirstElementByType(startNode, search) {
if (! startNode.hasChildNodes()) return null;
var children = startNode.childNodes;
var i;
for (i = 0; i < children.length; i ++) {
if (children[i].nodeName.toUpperCase() == search.toUpperCase()) {
return children[i];
}
}
}
// Resize scroll area to window size.
function ResizeScrollArea()
{
var height = getInnerHeight() - findPosY(divHeaderRow) - 75;
if (!vertical)
{
height -= divHeaderRow.offsetHeight;
}
var width = getInnerWidth() - 50;
if (!horizontal)
{
width -= divHeaderColumn.offsetWidth;
}
var headerRowsWidth = 0;
// divContent.childNodes[0].style.width = x + 'px';
// divContent.childNodes[0].style.height = y + 'px';
if (divHeaderRowColumn != null)
{
headerRowsWidth = divHeaderRowColumn.offsetWidth;
}
// width
if (findFirstElementByType(divContent, 'table').offsetWidth > width)
{
divContent.style.width = Math.max(width - headerRowsWidth, 0) + 'px';
divContent.style.overflowX = "scroll";
divContent.style.overflowY = "auto";
}
else
{
divContent.style.width = x + 'px';
divContent.style.overflowX = "auto";
divContent.style.overflowY = "auto";
}
if (divHeaderRow != null)
{
divHeaderRow.style.width = (divContent.offsetWidth + headerRowsWidth) + 'px';
}
// height
if (findFirstElementByType(divContent, 'table').offsetHeight > height)
{
divContent.style.height = Math.max(height, 80) + 'px';
divContent.style.overflowY = "scroll";
}
else
{
divContent.style.height = y + 'px';
divContent.style.overflowY = "hidden";
}
if (divHeaderColumn != null)
{
divHeaderColumn.style.height = divContent.offsetHeight + 'px';
}
// check scrollbars
if (divContent.style.overflowY == "scroll")
{
divContent.style.width = (divContent.offsetWidth + 17) + 'px';
}
if (divContent.style.overflowX == "scroll")
{
divContent.style.height = (divContent.offsetHeight + 17) + 'px';
}
divContent.parentNode.style.width = (divContent.offsetWidth + headerRowsWidth) + 'px';
}
// next two functions from quirksmode.org
function getInnerHeight() {
var y;
if (self.innerHeight) // all except Explorer
{
y = self.innerHeight;
}
else if (document.documentElement && document.documentElement.clientHeight)
// Explorer 6 Strict Mode
{
y = document.documentElement.clientHeight;
}
else if (document.body) // other Explorers
{
y = document.body.clientHeight;
}
return y;
}
function getInnerWidth() {
var x;
if (self.innerWidth) // all except Explorer
{
x = self.innerWidth;
}
else if (document.documentElement && document.documentElement.clientWidth)
// Explorer 6 Strict Mode
{
x = document.documentElement.clientWidth;
}
else if (document.body) // other Explorers
{
x = document.body.clientWidth;
}
return x;
}
// ********************************************************************************
// Synchronize div elements when scrolling
// from http://webfx.eae.net/dhtml/syncscroll/syncscroll.html
// ********************************************************************************
// This is a function that returns a function that is used
// in the event listener
function getOnScrollFunction(oElement, srcElement) {
return function () {
if (oElement._scrollSyncDirection == "horizontal" || oElement._scrollSyncDirection == "both")
oElement.scrollLeft = srcElement.scrollLeft;
if (oElement._scrollSyncDirection == "vertical" || oElement._scrollSyncDirection == "both")
oElement.scrollTop = srcElement.scrollTop;
};
}
// This function adds scroll syncronization for the fromElement to the toElement
// this means that the fromElement will be updated when the toElement is scrolled
function addScrollSynchronization(fromElement, toElement, direction) {
removeScrollSynchronization(fromElement);
fromElement._syncScroll = getOnScrollFunction(fromElement, toElement);
fromElement._scrollSyncDirection = direction;
fromElement._syncTo = toElement;
if (toElement.addEventListener) {
toElement.addEventListener("scroll", fromElement._syncScroll, false);
} else {
toElement.attachEvent("onscroll", fromElement._syncScroll);
}
}
// removes the scroll synchronization for an element
function removeScrollSynchronization(fromElement) {
if (fromElement._syncTo != null) {
if (fromElement._syncTo.removeEventListener) {
fromElement._syncTo.removeEventListener("scroll", fromElement._syncScroll, false);
} else {
fromElement._syncTo.detachEvent("onscroll", fromElement._syncScroll);
}
}
fromElement._syncTo = null;
fromElement._syncScroll = null;
fromElement._scrollSyncDirection = null;
}
// browser detection routines from quirksmode.org
var BrowserDetect = {
init: function () {
this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
this.version = this.searchVersion(navigator.userAgent)
|| this.searchVersion(navigator.appVersion)
|| "an unknown version";
this.OS = this.searchString(this.dataOS) || "an unknown OS";
},
searchString: function (data) {
for (var i=0;i<data.length;i++) {
var dataString = data[i].string;
var dataProp = data[i].prop;
this.versionSearchString = data[i].versionSearch || data[i].identity;
if (dataString) {
if (dataString.indexOf(data[i].subString) != -1)
return data[i].identity;
}
else if (dataProp)
return data[i].identity;
}
},
searchVersion: function (dataString) {
var index = dataString.indexOf(this.versionSearchString);
if (index == -1) return;
return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
},
dataBrowser: [
{ string: navigator.userAgent,
subString: "OmniWeb",
versionSearch: "OmniWeb/",
identity: "OmniWeb"
},
{
string: navigator.vendor,
subString: "Apple",
identity: "Safari"
},
{
prop: window.opera,
identity: "Opera"
},
{
string: navigator.vendor,
subString: "iCab",
identity: "iCab"
},
{
string: navigator.vendor,
subString: "KDE",
identity: "Konqueror"
},
{
string: navigator.userAgent,
subString: "Firefox",
identity: "Firefox"
},
{
string: navigator.vendor,
subString: "Camino",
identity: "Camino"
},
{ // for newer Netscapes (6+)
string: navigator.userAgent,
subString: "Netscape",
identity: "Netscape"
},
{
string: navigator.userAgent,
subString: "MSIE",
identity: "Explorer",
versionSearch: "MSIE"
},
{
string: navigator.userAgent,
subString: "Gecko",
identity: "Mozilla",
versionSearch: "rv"
},
{ // for older Netscapes (4-)
string: navigator.userAgent,
subString: "Mozilla",
identity: "Netscape",
versionSearch: "Mozilla"
}
],
dataOS : [
{
string: navigator.platform,
subString: "Win",
identity: "Windows"
},
{
string: navigator.platform,
subString: "Mac",
identity: "Mac"
},
{
string: navigator.platform,
subString: "Linux",
identity: "Linux"
}
]
};
BrowserDetect.init();
I hope this helps somebody, and thank you Karin for a great idea.
kdb
-- modified at 22:53 Tuesday 10th October, 2006
|
|
|
|
|
The function findPosY is missing.
|
|
|
|
|
Hi,
Thanks for this good script
I found that from http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_21761515.html:
function findPosY(obj) {<br />
var curTop= obj.offsetTop;<br />
while((obj= obj.offsetParent) != null) {<br />
curTop+= obj.offsetTop;<br />
}
return curTop;<br />
}
Put it in the script and all work (I tested on Firefox 3.5.16 and IE8)
I hope this will help you
Herve
|
|
|
|
|
Hello all, thank you Karin for a wonderful script. I like this one much better than the one posted on your blog because it degrades gracefully if the javascript doesn't work or is disabled.
That said, I have modified your script to work in both firefox and IE. The modified code follows.
<br />
var divContent = null;<br />
var divHeaderRow = null;<br />
var divHeaderColumn = null;<br />
var divHeaderRowColumn = null;<br />
var headerRowFirstColumn = null;<br />
var x;<br />
var y;<br />
var horizontal = false;<br />
var vertical = false;<br />
var childElement = 0;<br />
<br />
function CreateScrollHeader(content, scrollHorizontal, scrollVertical)<br />
{<br />
horizontal = scrollHorizontal;<br />
vertical = scrollVertical;<br />
<br />
if (content != null)<br />
{<br />
divContent = content;<br />
<br />
if (divContent.childNodes[childElement].tagName == null)<br />
{<br />
childElement = 1;<br />
}<br />
<br />
var headerRow = divContent.childNodes[childElement].childNodes[childElement];<br />
x = divContent.childNodes[childElement].offsetWidth;<br />
y = divContent.childNodes[childElement].offsetHeight; <br />
<br />
divHeaderRow = divContent.cloneNode(true); <br />
if (horizontal)<br />
{<br />
divHeaderRow.style.height = headerRow.offsetHeight + 'px';<br />
divHeaderRow.style.overflow = "hidden";<br />
<br />
divContent.parentNode.insertBefore(divHeaderRow, divContent);<br />
divContent.childNodes[childElement].style.position = "absolute";<br />
divContent.childNodes[childElement].style.top = "-" + headerRow.offsetHeight + 'px';<br />
<br />
y = y - headerRow.offsetHeight;<br />
}<br />
<br />
divHeaderRowColumn = divHeaderRow.cloneNode(true); <br />
headerRowFirstColumn = headerRow.childNodes[childElement].childNodes[childElement];<br />
divHeaderColumn = divContent.cloneNode(true);<br />
divContent.style.position = "relative";<br />
<br />
if (vertical)<br />
{<br />
divContent.parentNode.insertBefore(divHeaderColumn, divContent);<br />
divContent.style.left = headerRowFirstColumn.offsetWidth + 'px';<br />
<br />
divContent.childNodes[childElement].style.position = "absolute";<br />
divContent.childNodes[childElement].style.left = "-" + headerRowFirstColumn.offsetWidth + 'px';<br />
}<br />
else<br />
{<br />
divContent.style.left = "0px";<br />
}<br />
<br />
if (vertical)<br />
{<br />
divHeaderColumn.style.width = headerRowFirstColumn.offsetWidth + 'px';<br />
divHeaderColumn.style.overflow = "hidden";<br />
divHeaderColumn.style.zIndex = "99";<br />
<br />
divHeaderColumn.style.position = "absolute";<br />
divHeaderColumn.style.left = "0px";<br />
addScrollSynchronization(divHeaderColumn, divContent, "vertical");<br />
x = x - headerRowFirstColumn.offsetWidth;<br />
}<br />
<br />
if (horizontal)<br />
{<br />
if (vertical)<br />
{<br />
divContent.parentNode.insertBefore(divHeaderRowColumn, divContent);<br />
}<br />
divHeaderRowColumn.style.position = "absolute";<br />
divHeaderRowColumn.style.left = "0px";<br />
divHeaderRowColumn.style.top = "0px";<br />
divHeaderRowColumn.style.width = headerRowFirstColumn.offsetWidth + 'px';<br />
divHeaderRowColumn.overflow = "hidden";<br />
divHeaderRowColumn.style.zIndex = "100";<br />
divHeaderRowColumn.style.backgroundColor = "#ffffff";<br />
<br />
}<br />
<br />
if (horizontal)<br />
{<br />
addScrollSynchronization(divHeaderRow, divContent, "horizontal");<br />
}<br />
<br />
if (horizontal || vertical)<br />
{<br />
window.onresize = ResizeScrollArea;<br />
ResizeScrollArea();<br />
}<br />
}<br />
}<br />
<br />
<br />
function ResizeScrollArea()<br />
{<br />
var height = document.documentElement.clientHeight - 120;<br />
if (!vertical)<br />
{<br />
height -= divHeaderRow.offsetHeight;<br />
}<br />
var width = document.documentElement.clientWidth - 50;<br />
if (!horizontal)<br />
{<br />
width -= divHeaderColumn.offsetWidth;<br />
}<br />
var headerRowsWidth = 0;<br />
divContent.childNodes[childElement].style.width = x + 'px';<br />
divContent.childNodes[childElement].style.height = y + 'px';<br />
<br />
if (divHeaderRowColumn != null)<br />
{<br />
headerRowsWidth = divHeaderRowColumn.offsetWidth;<br />
}<br />
<br />
if (divContent.childNodes[childElement].offsetWidth > width)<br />
{<br />
divContent.style.width = Math.max(width - headerRowsWidth, 0) + 'px';<br />
divContent.style.overflowX = "scroll";<br />
divContent.style.overflowY = "auto";<br />
}<br />
else<br />
{<br />
divContent.style.width = x + 'px';<br />
divContent.style.overflowX = "auto";<br />
divContent.style.overflowY = "auto";<br />
}<br />
<br />
if (divHeaderRow != null)<br />
{<br />
divHeaderRow.style.width = (divContent.offsetWidth + headerRowsWidth) + 'px';<br />
}<br />
<br />
if (divContent.childNodes[childElement].offsetHeight > height)<br />
{<br />
divContent.style.height = Math.max(height, 80) + 'px';<br />
divContent.style.overflowY = "scroll";<br />
}<br />
else<br />
{<br />
divContent.style.height = y + 'px';<br />
divContent.style.overflowY = "hidden";<br />
}<br />
if (divHeaderColumn != null)<br />
{<br />
divHeaderColumn.style.height = divContent.offsetHeight + 'px';<br />
}<br />
<br />
if (divContent.style.overflowY == "scroll")<br />
{<br />
divContent.style.width = (divContent.offsetWidth + 17) + 'px';<br />
}<br />
if (divContent.style.overflowX == "scroll")<br />
{<br />
divContent.style.height = (divContent.offsetHeight + 17) + 'px';<br />
}<br />
<br />
divContent.parentNode.style.width = (divContent.offsetWidth + headerRowsWidth) + 'px';<br />
<br />
}<br />
<br />
<br />
function getOnScrollFunction(oElement, srcElement) {<br />
return function () {<br />
if (oElement._scrollSyncDirection == "horizontal" || oElement._scrollSyncDirection == "both")<br />
oElement.scrollLeft = srcElement.scrollLeft;<br />
if (oElement._scrollSyncDirection == "vertical" || oElement._scrollSyncDirection == "both")<br />
oElement.scrollTop = srcElement.scrollTop;<br />
};<br />
<br />
}<br />
<br />
function addScrollSynchronization(fromElement, toElement, direction) {<br />
removeScrollSynchronization(fromElement);<br />
<br />
fromElement._syncScroll = getOnScrollFunction(fromElement, toElement);<br />
fromElement._scrollSyncDirection = direction;<br />
fromElement._syncTo = toElement;<br />
if (toElement.addEventListener) {<br />
toElement.addEventListener("scroll", fromElement._syncScroll, false);<br />
} else {<br />
toElement.attachEvent("onscroll", fromElement._syncScroll);<br />
}<br />
}<br />
<br />
function removeScrollSynchronization(fromElement) {<br />
if (fromElement._syncTo != null) {<br />
if (fromElement._syncTo.removeEventListener) {<br />
fromElement._syncTo.removeEventListener("scroll", fromElement._syncScroll, false);<br />
} else {<br />
fromElement._syncTo.detachEvent("onscroll", fromElement._syncScroll);<br />
}<br />
}<br />
<br />
fromElement._syncTo = null;<br />
fromElement._syncScroll = null;<br />
fromElement._scrollSyncDirection = null;<br />
}<br />
This new code expects you to have a thead tag surrounding your top table headers, this allows you to split up more of the table than just the very top row. If you don't want this, you will have to modify lines 27 and 45 to be:
<br />
var headerRow = divContent.childNodes[childElement].childNodes[childElement].childNodes[0];<br />
<br />
headerRowFirstColumn = headerRow.childNodes[childElement];<br />
Enjoy.
kdb
|
|
|
|
|
Thankx kdb this code works well with both IE & FireFox
|
|
|
|
|
Hi,
Your article is very good. Thanks god I found yours.
But until now, I had problem with this when using Ctrl-F to find some text on the grid.
The grid strangely behaves, just try it yourself. I'm guess this issue occurs because you duplicate the content table into 2->4, and then when IE try to find a specific text, it find on the original one either on the others copied ones.
Does anyone have the same problem as me?
Hope to receive help from all of you.
Thanks
|
|
|
|
|
I need that when each line of the table will be clicked, a new line that this occults either shown, but am not obtaining therefore I occur error of Javascript, what I could make?
below, fragment my code:
<br />
<script><br />
function view(){<br />
subitem.style.display='';<br />
}<br />
</script><br />
<!--div id="outerDiv"--><br />
<!--div id="innerDiv"--><br />
<div id="outerDiv"><br />
<div id="innerDiv"><br />
<table border=1 id=main><br />
<tr><br />
<th>Table</th><br />
<th >Column 1</th><br />
<th>Column 2</th><br />
<th>Column 3</th><br />
<th>Column 4</th><br />
</tr><br />
<tr <!--onclick-->onclick="view();"><br />
<th>Row 1</th><br />
<td>Value 1 </td><br />
<td>Value 2</td><br />
<td>Value 3</td><br />
<td>Value 4</td><br />
</tr><br />
<tr style="display:none" id=subitem><br />
<th>Sub Item Row 1 >></th><br />
<td>Value 1 </td><br />
<td>Value 2</td><br />
<td>Value 3</td><br />
<td>Value 4</td><br />
</tr><br />
</table><br />
<!--/div--><br />
<!--/div--><br />
Adriano
-- modified at 12:55 Tuesday 25th July, 2006
|
|
|
|
|
Why do you copy the entire tables? Why not make a solution where only the header row gets copied for the header and the frozen columns get copied for the left div? And all this could be packaged real nice into a server control.
Jason Gilley
|
|
|
|
|
Jason,
Sounds to me like you have the makings of a CodeProject article. Go for it, dude! Show us how to do what you said.
Dwight
|
|
|
|
|
I copy the entire table because then I do not have to care about the width of the columns. Otherwise the content in the header row might be smaller than the content in the body (or the other way round), then I would have to synchronize them. As it is not possible to set the width of a TD I would have to insert a DIV into each TD and set the width of the DIV.
I did something similar in my cross browser solution (http://www.cubido.at/Blog/tabid/176/EntryID/94/Default.aspx[^]) but for large tables synchronizing the columns takes more time than copying the entire table (only in Internet Explorer).
Visit my blog at http://www.cubido.at/karin
|
|
|
|
|
I see what your talking about with the maximum column width, but you can set the size of a td also by using a 1 pixel transparent gif that you set a width to instead of a div, and the browser cant size this down on you.
|
|
|
|
|
I decided not to use images because:
1) it would destroy my layout, 1px height is small but it is still visible, so it would be necessary to change the style (padding, margin, ...) for TD's with images to make them look like normal TD's
2) in the first column of the first row 2 images would be necessary to adjust width and height in one cell, 1 image for width and height is not possible because the space is required for the content of the cell, this would cause some more problems with layout
Visit my blog at http://www.cubido.at/karin
|
|
|
|
|
Nice idea to duplicate the entire table - saves the trouble of writing script to match up the column widths. However with a really large table, won't your implementation use up a lot more memory since it has 4 copies of the large table?
|
|
|
|
|
|
Congrats - as far as I know you've made the first cross-browser scrolling table that can freeze the left-hand column as well as the header. My cross-browser ScrollingGrid only freezes the header.. I never got around to the column-locking solution. But both our solutions' approach to the problem are very similar (i.e. seperate tables and syncing the scroll position when the content cells are scrolled).
"Nothing ever changes by staying the same." - David Brent (BBC's The Office) ~ ScrollingGrid: A cross-browser 2-way-scrolling freeze-header control for the ASP.NET DataGrid
|
|
|
|
|
any ideas on why this does not work in firefox ?
|
|
|
|
|
Here is a cross-browser ASP.NET control that also uses synchronized scrolling and is Firefox compatible:
http://www.codeproject.com/aspnet/ScrollingGrid.asp[^]
I'll be updating the article in the next week or so with the new version of the control.
"... This man is obviously a psychotic."
"We-he-ell, uh, I'd like to hold off judgement on a thing like that, sir, until all the facts are in."
(Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb)
~ ScrollingGrid (cross-browser freeze-header control)
|
|
|
|
|
thanks, but I need a javascript solution...
|
|
|
|
|
All the scrolling functionality is done with JavaScript. Take a look at the new demo URL: http://www.ixnay2infinity.com/scrollinggrid/demo.aspx[^]
You can copy the HTML & JS file and use whatever server script you like (or none).
Note that this ScrollingGrid only freezes the header, but can't freeze the left-hand column(s) like some IE-only solutions.
"... This man is obviously a psychotic."
"We-he-ell, uh, I'd like to hold off judgement on a thing like that, sir, until all the facts are in."
(Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb)
~ ScrollingGrid (cross-browser freeze-header control)
|
|
|
|
|
very nice, but I need both top and left freezing....
|
|
|
|
|
Unfortunatly I did not get it to work in Firefox until now. But there is another solution which works in IE and in Firefox: http://www.cubido.at/Blog/tabid/176/EntryID/94/Default.aspx[^].
The main disadvantage of the cross brower solution is that for really large tables it works much slower in IE than the other solution.
Visit my blog at http://www.cubido.at/karin
-- modified at 11:58 Thursday 29th June, 2006
|
|
|
|
|