Data Browser - Viewing Site  Sector 23 Code Bank Logged in as:  Guest  




           


Custom .NET Responsive Html Table that is mobile-friendly
Web layouts are often in a table format using an html Table item. For example, rendering content into a 4 x 8 table, with different custom controls/layout in each cell.

This table can be several columns wide, which looks okay on a computer but is much too wide for a mobile device.

Many recommending using CSS layouts instead of HTML tables to allow columns to wrap - however, an HTML table is an easy way to guarantee an exact layout, whereas CSS layouts can wrap at arbitrary positions that can result in a difficult to read table. Text wrapping and styles within the cells are also difficult to line up.

Other solutions involve using CSS/JS to force the table into 2 columns, one for headers and one for the data; this is okay for 'grid view' data with nothing more than a 'header' and a 'data' field, but this doesn't work if your table is used for complex LAYOUT and doesn't have "headers", or if you want control over the # of columns (for example it must be a multiple of 3). If your data has 'headers' you should probably be using a GridView or Repeater, whereas this solution is specifically for HTML tables used to control page layout.

A better solution to keep the benefits of a fixed table structure but support wrapping is to extend the Table class to force it to wrap exactly where you want it, depending on the screen width. For example, you could choose multiples of 2 or 3 columns before the wrap. Or more simply, you might just say 'use 2 columns if mobile, else use all columns'.

The WrappableTableControl has a property 'MobileColumnCount' where you can specify the # of columns to show before wrapping, if on a mobile device. If null (or not on a mobile device), all columns show. You can set this to a fixed, small number, or set it based on the screen width (you can query from JavaScript).

For example, if I have a table that is 8 columns wide, but on a mobile device I would like it to be 2 columns wide and wrap on every 3rd column, I would set MobileColumnCount = 2.

If you have column spans it will truncate them as appropriate. You must ensure rowspans are in proper multiples for your mobile column count in order for them to work.

/// <summary>
/// Enhances html table with mobile-friendly layouts.
/// </summary>
[Designer("System.Web.UI.Design.WebControls.TableDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
[DefaultProperty("Rows")]
[ParseChildren(true, "Rows")]
[SupportsEventValidation]
public class WrappableTableControl : Table
{
/// <summary>
/// # of columns per row if mobile, will wrap addtl cols to next row.
/// </summary>
public int? MobileColumnCount
{
get
{
return (int?)ViewState["vsMCC"];
}
set
{
ViewState["vsMCC"] = value;
}
}

protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)
{
bool _supportMobileWrapping = MobileColumnCount.HasValue && this.Page != null && Page.Request != null &&
Page.Request.Browser != null && Page.Request.Browser.IsMobileDevice;

foreach (Control tr in this.Controls)
{
if (tr is TableRow && _supportMobileWrapping && tr.Visible)
{
(tr as TableRow).RenderBeginTag(writer); // start row
int colIx = 0;
foreach (Control td in tr.Controls)
{
if (td is TableCell && td.Visible)
{
if (colIx >= MobileColumnCount.Value)
{ // need new row.
(tr as TableRow).RenderEndTag(writer); // end row
(tr as TableRow).RenderBeginTag(writer); // start row
colIx = 0;
}

// make sure col span is okay
if (colIx + (td as TableCell).ColumnSpan > MobileColumnCount.Value)
{
(td as TableCell).ColumnSpan = MobileColumnCount.Value - colIx;
}

td.RenderControl(writer);
if ((td as TableCell).ColumnSpan > 1)
colIx += (td as TableCell).ColumnSpan;
else
colIx++;
}
else
td.RenderControl(writer);
}
(tr as TableRow).RenderEndTag(writer); // end row
}
else
tr.RenderControl(writer);
}
}
} // class

USAGE:
Shows 2 cols in mobile, 4 in PC:

<cc:WrappableTableControl runat="server" ID="tbTest" MobileColumnCount="2">
<asp:TableRow ID="TableRow1" runat="server">
<asp:TableCell ID="TableCell1" runat="server">Name:</asp:TableCell>
<asp:TableCell ID="TableCell2" runat="server">Jim</asp:TableCell>
<asp:TableCell ID="RmsTD1" runat="server">Phone:</asp:TableCell>
<asp:TableCell ID="RmsTD2" runat="server">3424033442</asp:TableCell>
</asp:TableRow>
<asp:TableRow ID="TableRow2" runat="server">
<asp:TableCell ID="TableCell3" runat="server">Name:</asp:TableCell>
<asp:TableCell ID="TableCell4" runat="server">Dan</asp:TableCell>
<asp:TableCell ID="TableCell5" runat="server">Phone:</asp:TableCell>
<asp:TableCell ID="TableCell6" runat="server">95937259</asp:TableCell>
</asp:TableRow>
<asp:TableRow ID="TableRow2" runat="server">
<asp:TableCell ID="TableCell3" runat="server">Name:</asp:TableCell>
<asp:TableCell ID="TableCell4" runat="server">Fred</asp:TableCell>
<asp:TableCell ID="TableCell5" runat="server" ColumnSpan="2">two columns</asp:TableCell>
</asp:TableRow>
</cc:WrappableTableControl>

Created By: amos 10/6/2014 2:55:43 PM
Updated: 10/10/2014 3:32:08 PM