I am currently trying to implement a GridView with a frozen header. I've gotten the header frozen using javascript found online. Here is the code:
var GridId = "<%=dgContacts.ClientID %>";
var ScrollHeight = 180;
var ScrollWidth = 700;
window.onload = function () {
enablePostLog();
var grid = document.getElementById(GridId);
var gridWidth = grid.offsetWidth;
var headerCellWidths = new Array();
for (var i = 0; i < grid.getElementsByTagName("TH").length; i++) {
headerCellWidths[i] = grid.getElementsByTagName("TH")[i].offsetWidth;
}
grid.parentNode.appendChild(document.createElement("div"));
var parentDiv = grid.parentNode;
var table = document.createElement("table");
for (i = 0; i < grid.attributes.length; i++) {
if (grid.attributes[i].specified && grid.attributes[i].name != "id") {
table.setAttribute(grid.attributes[i].name, grid.attributes[i].value);
}
}
table.style.cssText = grid.style.cssText;
table.style.width = gridWidth + "px";
table.style.tableLayout = "fixed";
table.appendChild(document.createElement("tbody"));
table.getElementsByTagName("tbody")[0].appendChild(grid.getElementsByTagName("TR")[0]);
var headerRow = table.getElementsByTagName("TH");
var gridRow = grid.getElementsByTagName("TR")[0];
for (var i = 0; i < headerRow.length; i++) {
var width;
if (headerCellWidths[i] > gridRow.getElementsByTagName("TD")[i].offsetWidth) {
width = headerCellWidths[i];
}
else {
width = gridRow.getElementsByTagName("TD")[i].offsetWidth;
}
headerRow[i].style.width = parseInt(width - 3) + "px";
gridRow.getElementsByTagName("TD")[i].style.width = parseInt(width - 3) + "px";
}
parentDiv.removeChild(grid);
var dummyHeader = document.createElement("div");
dummyHeader.setAttribute('id', 'divHeader');
dummyHeader.style.cssText = "margin-left: auto; margin-right: auto; overflow: hidden; width: " + ScrollWidth + "px";
dummyHeader.appendChild(table);
parentDiv.appendChild(dummyHeader);
var scrollableDiv = document.createElement("div");
gridWidth = parseInt(gridWidth) + 17;
scrollableDiv.setAttribute('id', 'divBody');
scrollableDiv.style.cssText = "margin-left: auto; margin-right: auto; overflow: auto; height: " + ScrollHeight + "px; width: " + ScrollWidth + "px";
scrollableDiv.appendChild(grid);
scrollableDiv.onscroll = scrollHeader;
parentDiv.appendChild(scrollableDiv);
}
function scrollHeader() {
var header = document.getElementById('divHeader');
var body = document.getElementById('divBody');
header.scrollLeft = body.scrollLeft;
}
The problem I'm having is that the GridView being in a fixed-width div. The width styles added to the columns is being ignored.
The final HTML looks like this: .png
The actual table rendered looks like this (the problem is most noticable in the "View" and "Notify" columns): .png
If I remove the fixed width on the outer div, the column widths correct themselves, but obviously, I lose my scrollability. It appears to be trying to shrink the whitespace in the table cells to try and fit into the div. This isn't necessary because of the overflow: auto
on the outer div. Is there a style or something I can add to stop the browser from doing this?
I am currently trying to implement a GridView with a frozen header. I've gotten the header frozen using javascript found online. Here is the code:
var GridId = "<%=dgContacts.ClientID %>";
var ScrollHeight = 180;
var ScrollWidth = 700;
window.onload = function () {
enablePostLog();
var grid = document.getElementById(GridId);
var gridWidth = grid.offsetWidth;
var headerCellWidths = new Array();
for (var i = 0; i < grid.getElementsByTagName("TH").length; i++) {
headerCellWidths[i] = grid.getElementsByTagName("TH")[i].offsetWidth;
}
grid.parentNode.appendChild(document.createElement("div"));
var parentDiv = grid.parentNode;
var table = document.createElement("table");
for (i = 0; i < grid.attributes.length; i++) {
if (grid.attributes[i].specified && grid.attributes[i].name != "id") {
table.setAttribute(grid.attributes[i].name, grid.attributes[i].value);
}
}
table.style.cssText = grid.style.cssText;
table.style.width = gridWidth + "px";
table.style.tableLayout = "fixed";
table.appendChild(document.createElement("tbody"));
table.getElementsByTagName("tbody")[0].appendChild(grid.getElementsByTagName("TR")[0]);
var headerRow = table.getElementsByTagName("TH");
var gridRow = grid.getElementsByTagName("TR")[0];
for (var i = 0; i < headerRow.length; i++) {
var width;
if (headerCellWidths[i] > gridRow.getElementsByTagName("TD")[i].offsetWidth) {
width = headerCellWidths[i];
}
else {
width = gridRow.getElementsByTagName("TD")[i].offsetWidth;
}
headerRow[i].style.width = parseInt(width - 3) + "px";
gridRow.getElementsByTagName("TD")[i].style.width = parseInt(width - 3) + "px";
}
parentDiv.removeChild(grid);
var dummyHeader = document.createElement("div");
dummyHeader.setAttribute('id', 'divHeader');
dummyHeader.style.cssText = "margin-left: auto; margin-right: auto; overflow: hidden; width: " + ScrollWidth + "px";
dummyHeader.appendChild(table);
parentDiv.appendChild(dummyHeader);
var scrollableDiv = document.createElement("div");
gridWidth = parseInt(gridWidth) + 17;
scrollableDiv.setAttribute('id', 'divBody');
scrollableDiv.style.cssText = "margin-left: auto; margin-right: auto; overflow: auto; height: " + ScrollHeight + "px; width: " + ScrollWidth + "px";
scrollableDiv.appendChild(grid);
scrollableDiv.onscroll = scrollHeader;
parentDiv.appendChild(scrollableDiv);
}
function scrollHeader() {
var header = document.getElementById('divHeader');
var body = document.getElementById('divBody');
header.scrollLeft = body.scrollLeft;
}
The problem I'm having is that the GridView being in a fixed-width div. The width styles added to the columns is being ignored.
The final HTML looks like this: https://i.sstatic/xDzez.png
The actual table rendered looks like this (the problem is most noticable in the "View" and "Notify" columns): https://i.sstatic/rA35z.png
If I remove the fixed width on the outer div, the column widths correct themselves, but obviously, I lose my scrollability. It appears to be trying to shrink the whitespace in the table cells to try and fit into the div. This isn't necessary because of the overflow: auto
on the outer div. Is there a style or something I can add to stop the browser from doing this?
-
1
Hey..I have used same type of script. I have a grid with 5000 records. When I call this script on
window.onload()
page gets blocked until the script executed. It Effects performance. Can u guide me how to improve performance – JayOnDotNet Commented Jun 7, 2012 at 9:30
1 Answer
Reset to default 6Turns out I needed table-layout: fixed
AND width: 100%
to both tables. I had tried the table-layout solution, but didn't realize about the width needing to be 100% as well.
Final javascript:
var GridId = "<%=dgContacts.ClientID %>";
var ScrollHeight = 180;
var ScrollWidth = 700;
window.onload = function () {
enablePostLog();
var grid = document.getElementById(GridId);
var gridWidth = grid.offsetWidth;
var headerCellWidths = new Array();
for (var i = 0; i < grid.getElementsByTagName("TH").length; i++) {
headerCellWidths[i] = grid.getElementsByTagName("TH")[i].offsetWidth;
}
grid.parentNode.appendChild(document.createElement("div"));
var parentDiv = grid.parentNode;
var table = document.createElement("table");
for (i = 0; i < grid.attributes.length; i++) {
if (grid.attributes[i].specified && grid.attributes[i].name != "id") {
table.setAttribute(grid.attributes[i].name, grid.attributes[i].value);
}
}
table.style.cssText = grid.style.cssText;
table.appendChild(document.createElement("tbody"));
table.getElementsByTagName("tbody")[0].appendChild(grid.getElementsByTagName("TR")[0]);
var headerRow = table.getElementsByTagName("TH");
var gridRow = grid.getElementsByTagName("TR")[0];
for (var i = 0; i < headerRow.length; i++) {
var width;
if (headerCellWidths[i] > gridRow.getElementsByTagName("TD")[i].offsetWidth) {
width = headerCellWidths[i];
}
else {
width = gridRow.getElementsByTagName("TD")[i].offsetWidth;
}
gridRow.getElementsByTagName("TD")[i].style.width = parseInt(width - 3) + "px";
if (i == headerRow.length - 1) {
width = width + getScrollBarWidth();
}
headerRow[i].style.width = parseInt(width - 3) + "px";
}
parentDiv.removeChild(grid);
grid.style.tableLayout = "fixed";
table.style.tableLayout = "fixed";
grid.style.width = "100%";
table.style.width = "100%";
var dummyHeader = document.createElement("div");
dummyHeader.setAttribute('id', 'divHeader');
dummyHeader.style.cssText = "margin-left: auto; margin-right: auto; overflow: hidden; width: " + ScrollWidth + "px";
dummyHeader.appendChild(table);
parentDiv.appendChild(dummyHeader);
var scrollableDiv = document.createElement("div");
scrollableDiv.setAttribute('id', 'divBody');
scrollableDiv.style.cssText = "margin-left: auto; margin-right: auto; overflow: auto; height: " + ScrollHeight + "px; width: " + ScrollWidth + "px";
scrollableDiv.appendChild(grid);
scrollableDiv.onscroll = scrollHeader;
parentDiv.appendChild(scrollableDiv);
}
function scrollHeader() {
var header = document.getElementById('divHeader');
var body = document.getElementById('divBody');
header.scrollLeft = body.scrollLeft;
}
function getScrollBarWidth() {
var inner = document.createElement('p');
inner.style.width = "100%";
inner.style.height = "200px";
var outer = document.createElement('div');
outer.style.position = "absolute";
outer.style.top = "0px";
outer.style.left = "0px";
outer.style.visibility = "hidden";
outer.style.width = "200px";
outer.style.height = "150px";
outer.style.overflow = "hidden";
outer.appendChild(inner);
document.body.appendChild(outer);
var w1 = inner.offsetWidth;
outer.style.overflow = 'scroll';
var w2 = inner.offsetWidth;
if (w1 == w2) w2 = outer.clientWidth;
document.body.removeChild(outer);
return (w1 - w2);
}