enter code here
I have a gridview in some code I inherited that is using rowdatabound to add javascript to checkboxes. This is to enable the row checkboxes to be set by a master checkbox in the header. And that all works. The problem is performance. The users do not want paging, and some of these grids can have thousands of rows. Rendering is fast if we don’t use Attributes.Add() to hook up the javascript. If I do use rowdatabound for the javascript injection, performance goes from instantaneous to nearly a minute for a mere 600 rows. That’s not right.
So I have two questions:
1) Is it normal for rowdatabound to take forever to handle these javascript injections?
2) If so, what would you recommend as a faster alternative to setting up the row checkboxes to work with the master checkbox in the header?
And as I am new to the forum, I want to thank everyone here for help already received. I have been lurking for weeks now and you all have been quite impressive with your knowledge and willingness to help.
UPDATE:
Thanks everyone for your help. Here's what I ended up doing:
First, I had to set some variables in my aspx to capture clientID for a Master Page environment:
<script language="javascript" type="text/javascript">
//set the control id required by the external javascript
var ChangedAddressesGridViewID = '<%=ChangedAddressesGridView.ClientID%>';
</script>
Then I set the onclick for the header checkbox to the name of my header function, and also set the onclick for the child checkbox to the name of my child click function. I provided only three parameters, "this" for the clicked checkbox itself, the MasterPage friendly name of the GridView, and a number representing the column. Hard-coded, I know, but the columns are not dynmamic, so not an issue at this time:
<asp:GridView id="ChangedAddressesGridView" runat="server" AutoGenerateColumns="False" >
<Columns>
<asp:BoundField datafield="AddressId" headertext="ID" />
<asp:BoundField datafield="Code" headertext="Code" />
<asp:BoundField datafield="Facility" headertext="Facility" />
<asp:BoundField datafield="Address" headertext="Address" />
<asp:TemplateField headertext="Select">
<HeaderTemplate>
<asp:Label id="LBLOverride" runat="server" text="Override" font-size="Smaller" font-names="Arial"></asp:Label><br />
<asp:CheckBox id="chkBxHeader1" runat="server" onclick="HeaderClick(this,ChangedAddressesGridViewID,'4');"></asp:CheckBox> <br />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox id="chkBxSelect1" runat="server" onclick="ChildClick(this,ChangedAddressesGridViewID,'4');" ></asp:CheckBox>
</ItemTemplate>
<headerstyle horizontalalign="Center" />
<itemstyle horizontalalign="Center" />
</asp:TemplateField>
<asp:BoundField datafield="CAddress" headertext="Corrected Address" />
<asp:TemplateField headertext="Select">
<HeaderTemplate>
<asp:Label id="lblChange" runat="server" text="Change" font-size="Smaller" font-names="Arial"></asp:Label><br />
<asp:CheckBox id="chkBxHeader2" runat="server" onclick="HeaderClick(this,ChangedAddressesGridViewID,'6');"></asp:CheckBox>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox id="chkBxSelect2" runat="server" onclick="ChildClick(this,ChangedAddressesGridViewID,'6');"></asp:CheckBox>
</ItemTemplate>
<headerstyle horizontalalign="Center" />
<itemstyle horizontalalign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
Here's the JavaScript that makes it work:
function GetHeaderCheckBox(grid, cellnum) {
cell = grid.rows[0].cells[cellnum];
for (j = 0; j < cell.childNodes.length; j++) {
if (cell.childNodes[j].type == "checkbox") {return cell.childNodes[j]; }
}
return false;
}
function CheckBoxIsChecked(row, cellnum) {
cell = row.cells[cellnum];
for (j = 0; j < cell.childNodes.length; j++) {
if (cell.childNodes[j].type == "checkbox") {
return cell.childNodes[j].checked;
}
}
}
function SetCheckBox(row, cellnum, checkedValue) {
cell = row.cells[cellnum];
for (j = 0; j < cell.childNodes.length; j++) {
if (cell.childNodes[j].type == "checkbox") {
cell.childNodes[j].checked = checkedValue;
}
}
}
function HeaderClick(HeaderCheckBox, GridViewID, checkboxcolumn) {
var checkedValue;
var grid = document.getElementById(GridViewID);
var TotalChkBx = grid.rows.length;
if (HeaderCheckBox.checked == true) { checkedValue = true; } else { checkedValue = false; }
for (var n = 1; n < TotalChkBx; n++) {
SetCheckBox(grid.rows[n], checkboxcolumn, checkedValue);
};
}
function ChildClick(RowCheckBox, GridViewID, checkboxcolumn) {
var grid = document.getElementById(GridViewID);
var HeaderCheckBox = GetHeaderCheckBox(grid, checkboxcolumn);
var TotalChkBx = grid.rows.length;
var TotalChkBxChecked = 0;
for (var n = 1; n < TotalChkBx; n++) {
if (CheckBoxIsChecked(grid.rows[n], checkboxcolumn)) { TotalChkBxChecked++; }
};
if (TotalChkBxChecked == TotalChkBx - 1) { HeaderCheckBox.checked = true; } else { HeaderCheckBox.checked = false; }
}
There you have it. The one thing different about this than most similar examples is I wanted to go by columns rather than just spin through the "inputs" list. This is because I have two checkbox columns, and I wasn't sure how, with "inputs," I would be able to keep them separate without getting very messy. So I found an example that helped me see how to do this here:
http://technico.qnownow.com/how-to-delete-multiple-rows-from-gridview-with-checkboxes/
Also, to eliminate more unnecessary parameters, I had the child function figure out its header checkbox on its own.
Anyway, now I have a select-all header/child checkbox pattern I can drop in anywhere. The previous version had to look up a specific checkbox name, so it was limited to just that one column, which meant that you had to copy/paste the functionality wherever you needed it. Differences had crept in and I was getting inconsistent and wrong behavior. With this solution, so far, no errors, and the same exact behavior everywhere.
And no rowdatabound. Life is good.
Thanks again to everyone. You all helped me think through various parts of the problem.