ASP.net webgrid generate tfoot after tbody in html


I have a legacy application I've picked up and have a requirement to pass html5 validation and WCAG2.0 AA tests. I'm running into an issue with the System.Web.Helpers.Webgrid and the table it generates as the tfoot element is being generated before the tbody element which causes it to fail validation. Obviously this was fine years ago, but with the new validation rules, having a tfoot ahead of the tbody is no longer allowed.

Is there a way to force the webgrid to generate the tfoot element after the tbody element or some kind of easy workaround? Simply disabling the footer (no paging) isn't an option as sometimes the data returned will have hundreds of rows.

Code for generating table:

var grid = new WebGrid(source: Model.Stuff,
                       defaultSort: "Stamp",
                       rowsPerPage: 20,
                       fieldNamePrefix: "wg_",
                       canPage: true,
                       canSort: true,
                       pageFieldName: "pg");
<text>
@grid.GetHtml(tableStyle: "gridtable",
                headerStyle: "gridtableheading",
                rowStyle: "gridtablerow",
                alternatingRowStyle: "gridtablerowalternate",
                columns:
                    grid.Columns(
                                grid.Column("View", format: (item) => (Html.ActionLink("Select", "View", "Item", new { itemID = item.ID }, null)), style: "padtable centeralign"),
                                grid.Column("ID", "ID", style: "padtable rightalign"),
                                grid.Column("CreatedDate", "Stamp", format: (item) => String.Format("{0:MM/dd/yyyy hh:mm tt}", item.CreatedDate), style: "padtable leftalign"),
                                grid.Column("Type", "Type", style: "padtable rightalign"),
                                grid.Column("Status", "Status", style: "padtable leftalign"),
                     ), mode: WebGridPagerModes.Numeric)
</text>

Here's a generalized version of what that actually generates

<!DOCTYPE html>
<html lang="en-US">
<head>
  <title>Table Test</title>
</head>
<body>
  <table>
    <thead>
      <tr>
        <td>header1</td>
        <td>header2</td>
      </tr>
    </thead>
    <tfoot>
      <tr>
        <td>Previous page link</td>
        <td>Next page link</td>
      </tr>
    </tfoot>
    <tbody>
      <tr>
        <td>table row1 data 1</td>
        <td>table row1 data 2</td>
      </tr>
      <tr>
        <td>table row2 data 1</td>
        <td>table row2 data 2</td>
      </tr>
    </tbody>
  </table>
</body>

- - Source

Answers

answered 1 week ago slugolicious #1

The answer on ASP.NET GridView Newbie Questions About TFOOT and TH shows <tfoot> customizations and prior to the customizations, the <tfoot> was before the <tbody>, but after the customizations, the <tfoot> is now after the <tbody>. Perhaps there was something they did in the customizations that caused that. Worst case, you can customize it with something simple just to get the <tfoot> moved.

answered 5 day ago Sean Patterson #2

I wasn't able to find a way to do this automatically, however the idea of customizing the footer mentioned by slugolicious made me realize that it was likely just easier to edit the HTML to move the footer.

This is far from a generalized solution, but it easily moves the footer to the bottom of the table for the cases I need to solve.

string TableHTML = grid.GetHtml(tableStyle: "gridtable",
            headerStyle: "gridtableheading",
            rowStyle: "gridtablerow",
            alternatingRowStyle: "gridtablerowalternate",
            columns:
                grid.Columns(
                            grid.Column("View", format: (item) => (Html.ActionLink("Select", "View", "Item", new { itemID = item.ID }, null)), style: "padtable centeralign"),
                            grid.Column("ID", "ID", style: "padtable rightalign"),
                            grid.Column("CreatedDate", "Stamp", format: (item) => String.Format("{0:MM/dd/yyyy hh:mm tt}", item.CreatedDate), style: "padtable leftalign"),
                            grid.Column("Type", "Type", style: "padtable rightalign"),
                            grid.Column("Status", "Status", style: "padtable leftalign"),
                 ), mode: WebGridPagerModes.Numeric).ToHtmlString();


string TableFooter = TableHTML.Substring(TableHTML.IndexOf("<tfoot>"),TableHTML.IndexOf("</tfoot>") + 8 - TableHTML.IndexOf("<tfoot>")); //Grab the HTML for the footer
string NewTable = TableHTML.Substring(0, TableHTML.IndexOf("<tfoot>")); //Take the HTML up until the footer
NewTable += TableHTML.Substring(TableHTML.IndexOf("</tfoot>") + 8).Replace("</table>","");  //Omit the footer, grab the rest of the HTML, remove the closing tag
NewTable += TableFooter; //Reinsert the footer at the end
NewTable += "</table>"; //Add the closing tag

<text>
    @(new HtmlString(NewTable))
</text>

comments powered by Disqus