Answered by:
GridView Fixed Header issue: cannot get header with to set same as item.

Question
-
User-670301532 posted
I have been trying for several days to get a GridView to operate on the client screen with a fixed header and scrollable body so that the data will scroll up and down but the header stay where it is in relation to the data rows. The grid is dynamically generated and has the potential to have hundreds of rows. The user does not want paging. Only 3 columns are sortable. Yep, it's very custom. Primary CSS is Bootstrap (3.3.7). I'd appreciate any hints. Here's what I've got so far:
From the markup - styles and GridView:
<style type="text/css"> .gvScrollHeader table { width: 100%; } .gvScrollHeader thead tr:after { content: ' '; visibility: hidden; } .gvScrollHeader thead { display: block; position: relative; } .gvScrollHeader tbody { display: block; height: 100px; overflow-y: scroll; } </style>
<asp:GridView ID="gvActiveCandidates" runat="server" DataKeyNames="" AutoGenerateColumns="false" EnableViewState="false" CssClass="table table-hover table-bordered table-striped gvScrollHeader" AllowSorting="true" ShowHeaderWhenEmpty="true" AllowPaging="false" EmptyDataText="Criteria selected result in no candidates." OnSorting="gv_Sorting" OnRowCreated="gv_OnRowCreated" OnRowDataBound="gv_RowDataBound"> <SortedAscendingHeaderStyle CssClass="text-left SortASC" /> <SortedDescendingHeaderStyle CssClass="text-left SortDESC" /> </asp:GridView>Code behind bits:
DataTable dt = GetTheGridData(); if (dt != null) { // The data table is pre-processed here to populate the Columns property of the GridView. // There are a LOT of columns and I didn't want to set them all up specifically in the markup // then still have to manipulate them more in the code behind. foreach (DataColumn column in dt.Columns) { BoundField field = new BoundField(); field.DataField = column.ColumnName; field.HeaderText = column.ColumnName.Replace("_", " "); switch (column.ColumnName) { case "Road": case "Candidate_#": case "Estimated_Cost": field.SortExpression = column.ColumnName; break; }
// Some field string display formatting happens here based on clues in the HeaderText
field.HeaderStyle.Wrap = false; gvActiveCandidates.Columns.Add(field); } DataView dv = dt.DefaultView; // Sorting setup gets handled here. gvActiveCandidates.DataSource = dv; gvActiveCandidates.DataBind(); //This next pushes the rendering to give the <thead> and <tbody> tags in the markup
gvActiveCandidates.HeaderRow.TableSection = TableRowSection.TableHeader;
// later in the events for the gridview... I've tried in both RowDataBound and OnRowCreated to set the widths of
// the column headers programmatically to no avail. The thead and tbody look fine by themselves but I cannot get the columns
// in thead to line up with the columns in tbody and be the same width for display purposes.Monday, July 1, 2019 9:48 PM
Answers
-
User665608656 posted
Hi Russell,
According to your description,I recommend that you use datatable plug-in directly.
It's a Table plug-in for jQuery. Functions you need can be implemented in jQuery with short sentences.
You could refer to these link : https://datatables.net/
https://stackoverflow.com/questions/8200681/apply-jquery-datatables-plugin-to-asp-gridview
Based on your code,I made an example with this plug-in,you could refer to the following code:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css" /> <script src="https://code.jquery.com/jquery-3.3.1.js"></script> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script> <script type="text/javascript"> $(function () { $('#<%= gvActiveCandidates.ClientID %>').prepend($("<thead></thead>").append($(this).find("tr:first"))).dataTable({ paging: false,//disable paging scrollY: "100px", searching: false, info: false, order: [], columnDefs: [{ orderable: false, targets: [0, 1] }], //disable the first and second column to sort }); }); </script> <style type="text/css"> </style> </head> <body> <form id="form1" runat="server"> <div class="newcontainer" style="width: 800px"> <asp:GridView ID="gvActiveCandidates" runat="server" AutoGenerateColumns="False" EnableViewState="False"
ShowHeaderWhenEmpty="True" EmptyDataText="Criteria selected result in no candidates." OnRowDataBound="gvActiveCandidates_RowDataBound">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="IsSelected" HeaderText="IsSelected" SortExpression="IsSelected" />
</Columns>
</asp:GridView> </div> </form> </body> </html>The result of this work demo:
Best Regards,
YongQing.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, July 2, 2019 2:58 AM
All replies
-
User665608656 posted
Hi Russell,
According to your description,I recommend that you use datatable plug-in directly.
It's a Table plug-in for jQuery. Functions you need can be implemented in jQuery with short sentences.
You could refer to these link : https://datatables.net/
https://stackoverflow.com/questions/8200681/apply-jquery-datatables-plugin-to-asp-gridview
Based on your code,I made an example with this plug-in,you could refer to the following code:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css" /> <script src="https://code.jquery.com/jquery-3.3.1.js"></script> <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script> <script type="text/javascript"> $(function () { $('#<%= gvActiveCandidates.ClientID %>').prepend($("<thead></thead>").append($(this).find("tr:first"))).dataTable({ paging: false,//disable paging scrollY: "100px", searching: false, info: false, order: [], columnDefs: [{ orderable: false, targets: [0, 1] }], //disable the first and second column to sort }); }); </script> <style type="text/css"> </style> </head> <body> <form id="form1" runat="server"> <div class="newcontainer" style="width: 800px"> <asp:GridView ID="gvActiveCandidates" runat="server" AutoGenerateColumns="False" EnableViewState="False"
ShowHeaderWhenEmpty="True" EmptyDataText="Criteria selected result in no candidates." OnRowDataBound="gvActiveCandidates_RowDataBound">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="IsSelected" HeaderText="IsSelected" SortExpression="IsSelected" />
</Columns>
</asp:GridView> </div> </form> </body> </html>The result of this work demo:
Best Regards,
YongQing.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, July 2, 2019 2:58 AM -
User-670301532 posted
Thanks! I have marked your answer, thank you very much. A little tweaking of the options got me very close to what I want and I'm sure somewhere in the plugin's documentation and source site you referenced I'm going to find the fix for the minor thing introduced now. Using the scrollY attribute to limit height also adds a horizontal scroll and limits the display width of the tbody part to 100% of the display area, leaving the header extending to the right off the viewable area. Just need to either get the header to also scroll in sync or allow the body to extend as well and leave the browser's default behavior for default scrolling to the right. This is what the user is expecting since there are 48 columns in the table. The function of this display is purely a tool to preview data to be downloaded into Excel, not showing everything on one nice, tidy page.
Tuesday, July 2, 2019 2:45 PM