1

I've searched all over Google and Stack Overflow but I can't seem to find an answer.

I just want to add a <thead> tag to my GridView so that I can use a jQuery table sorter.

I add the <thead> section like so:

Protected Sub GvReportPreRender(ByVal sender As Object, ByVal e As EventArgs) Handles gvReport.PreRender
     If gvReport.Rows.Count > 0 Then
          gvReport.UseAccessibleHeader = True
          gvReport.HeaderRow.TableSection = TableRowSection.TableHeader
     End If
End Sub

However, I've found that it's failing because I use the following method to add custom rows and styling on RowDataBound. Is there any way I can add this custom header row, above the normal header, while keeping the <thead> tag, and without destroying any sort functionality I plan to implement with jQuery?

Private Sub StyleTable(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles gvReport.RowDataBound
            Dim useDollars As Boolean = False

            'Define arrays to color the gridview, if cell index is in array, it will be colored
            Dim blueArray() As Integer = {0, 17, 18, 19, 20}
            Dim greenArray() As Integer = {1, 2, 3, 4}
            Dim purpleArray() As Integer = {5, 6, 7, 8}
            Dim pinkArray() As Integer = {9, 10, 11, 12}
            Dim yellowArray() As Integer = {13, 14, 15, 16}

            If filterControl.SelectedMeasurement = "NetSales" Then
                useDollars = True
            End If

            _packworks.ColorizeMe(blueArray, greenArray, purpleArray, pinkArray, yellowArray, e.Row)

            If e.Row.RowType = DataControlRowType.Header Then
                Dim headerGridRow As New GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert)
                Dim headerCell As New TableCell()

                'Reset color arrays for headers
                blueArray = New Integer() {0, 5}
                greenArray = New Integer() {1}
                purpleArray = New Integer() {2}
                pinkArray = New Integer() {3}
                yellowArray = New Integer() {4}

                Dim lblForecastTotal As Label = CType(e.Row.FindControl("lblHForecast_total"), Label)
                Dim lblActualTotal As Label = CType(e.Row.FindControl("lblHActual_total"), Label)
                Dim lblForecastQ1 As Label = CType(e.Row.FindControl("lblHForecast_q1"), Label)
                Dim lblActualQ1 As Label = CType(e.Row.FindControl("lblHActual_q1"), Label)
                Dim lblForecastQ2 As Label = CType(e.Row.FindControl("lblHForecast_q2"), Label)
                Dim lblActualQ2 As Label = CType(e.Row.FindControl("lblHActual_q2"), Label)
                Dim lblForecastQ3 As Label = CType(e.Row.FindControl("lblHForecast_q3"), Label)
                Dim lblActualQ3 As Label = CType(e.Row.FindControl("lblHActual_q3"), Label)
                Dim lblForecastQ4 As Label = CType(e.Row.FindControl("lblHForecast_q4"), Label)
                Dim lblActualQ4 As Label = CType(e.Row.FindControl("lblHActual_q4"), Label)

                'Business wants to compare Year - 1 forecast data to Year actuals, so set labels
                'Accordingly.. Actual logic is applied when calling GetForecastTable() and
                'GetDnsTable()
                Dim lblArray() As Label = {lblActualTotal, lblActualQ1, lblActualQ2, _
                                           lblActualQ3, lblActualQ4}

                _packworks.SetHeaderText(filterControl.Oyear, lblArray, Nothing, gvReport)

                lblArray = New Label() {lblForecastTotal, lblForecastQ1, lblForecastQ2, _
                                        lblForecastQ3, lblForecastQ4}

                _packworks.SetHeaderText(filterControl.Oyear - 1, lblArray, Nothing, gvReport)

                headerCell.Text = "Account"
                headerCell.RowSpan = 2
                headerCell.HorizontalAlign = HorizontalAlign.Center
                e.Row.Cells(0).Visible = False
                headerGridRow.Cells.Add(headerCell)

                headerCell = New TableCell()
                headerCell.HorizontalAlign = HorizontalAlign.Center
                headerCell.Text = "Total Packworks" & IIf(useDollars, " ($)", String.Empty).ToString()
                headerCell.ColumnSpan = 4
                headerGridRow.Cells.Add(headerCell)

                headerCell = New TableCell()
                headerCell.HorizontalAlign = HorizontalAlign.Center
                headerCell.Text = "Total Q1 Packworks" & IIf(useDollars, " ($)", String.Empty).ToString()
                headerCell.ColumnSpan = 4
                headerGridRow.Cells.Add(headerCell)

                headerCell = New TableCell()
                headerCell.HorizontalAlign = HorizontalAlign.Center
                headerCell.Text = "Total Q2 Packworks" & IIf(useDollars, " ($)", String.Empty).ToString()
                headerCell.ColumnSpan = 4
                headerGridRow.Cells.Add(headerCell)

                headerCell = New TableCell()
                headerCell.HorizontalAlign = HorizontalAlign.Center
                headerCell.Text = "Total Q3 Packworks" & IIf(useDollars, " ($)", String.Empty).ToString()
                headerCell.ColumnSpan = 4
                headerGridRow.Cells.Add(headerCell)

                headerCell = New TableCell()
                headerCell.HorizontalAlign = HorizontalAlign.Center
                headerCell.Text = "Total Q4 Packworks" & IIf(useDollars, " ($)", String.Empty).ToString()
                headerCell.ColumnSpan = 4
                headerGridRow.Cells.Add(headerCell)

                _packworks.ColorizeMe(blueArray, greenArray, purpleArray, pinkArray, yellowArray, headerGridRow)
                gvReport.Controls(0).Controls.AddAt(0, headerGridRow)

            ElseIf e.Row.RowType = DataControlRowType.DataRow Then
                Dim lblVarianceTotal As Label = CType(e.Row.FindControl("lblVariance_total"), Label)
                Dim lblVarianceQ1 As Label = CType(e.Row.FindControl("lblVariance_q1"), Label)
                Dim lblVarianceQ2 As Label = CType(e.Row.FindControl("lblVariance_q2"), Label)
                Dim lblVarianceQ3 As Label = CType(e.Row.FindControl("lblVariance_q3"), Label)
                Dim lblVarianceQ4 As Label = CType(e.Row.FindControl("lblVariance_q4"), Label)
                Dim lblVarianceTotalPercent As Label = CType(e.Row.FindControl("lblVariance_total_percent"), Label)
                Dim lblVarianceQ1Percent As Label = CType(e.Row.FindControl("lblVariance_q1_percent"), Label)
                Dim lblVarianceQ2Percent As Label = CType(e.Row.FindControl("lblVariance_q2_percent"), Label)
                Dim lblVarianceQ3Percent As Label = CType(e.Row.FindControl("lblVariance_q3_percent"), Label)
                Dim lblVarianceQ4Percent As Label = CType(e.Row.FindControl("lblVariance_q4_percent"), Label)

                Dim lblArray() As Label = {lblVarianceTotal, lblVarianceQ1, lblVarianceQ2, lblVarianceQ3, _
                                            lblVarianceQ4, lblVarianceTotalPercent, lblVarianceQ1Percent, _
                                            lblVarianceQ2Percent, lblVarianceQ3Percent, lblVarianceQ4Percent}

                For Each lbl As Label In lblArray
                    _packworks.MakeNegativesRed(lbl)
                Next
            End If
        End Sub

2 Answers 2

3

Just use this:

Protected Sub GridView1_PreRender(sender As Object, e As System.EventArgs) Handles GridView1.PreRender
    GridView1.UseAccessibleHeader = True
    GridView1.HeaderRow.TableSection = TableRowSection.TableHeader
End Sub

Or with Javascript:

window.onload = function () {
    var grid = document.getElementById('<%= GridView1.ClientID %>');
    var tbody = grid.getElementsByTagName("tbody")[0]; //gets the first and only tbody
    var firstTr = tbody.getElementsByTagName("tr")[0]; //gets the first tr, hopefully contains the th's

    tbody.removeChild(firstTr); //remove tr's from table

    var newTh = document.createElement('thead'); //creates thead
    newTh.appendChild(firstTr); //puts ths in thead
    grid.insertBefore(newTh, tbody); //puts thead behore tbody

}

enter image description here

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for your help. Your JavaScript solution seems to be working, although it's causing some formatting issues. I've used that exact PreRender method, also checking to make sure GridView1.Rows.Count > 0, and it's throwing the same error--`Table must contain row sections in order of body, header, footer. Adding the Gridview markup to my original post now.
@TimeBomb006 did you use the global PreRender or the GridView prerender like I have it in my code?
see latest update. I was adding a custom row above the header on RowDataBound, which I thought I had commented out, which was throwing that error. I'd like to keep this row AND add the <thead> tag for jQuery sorting purposes.
I don't get it, you have one row above the row you want to use as a thead? I think that would be malformed table element.
0
GridView1.UseAccessibleHeader = True

Just remove this line from the above code.

I used it in the Page_Load event.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.