views:

60

answers:

3

Given the following HTML:

<asp:content id="Content1" contentplaceholderid="mainContent" runat="server">

<div class="scrollRow">
    <table width="100%">
        <tr>
            <td width="25%">Site name: <b>My site</b></td>
            <td>Created on 12th Aug 2010</td>
            <td align="right"><button onclick="doRevert(1)">Revert to this</button></td>
        </tr>
    </table>
</div>

<div class="scrollRow">
    <table width="100%">
        <tr>
            <td width="25%">Site name: <b>Another site</b></td>
            <td>Created on 3rd Aug 2010</td>
            <td align="right"><button onclick="doRevert(1)">Revert to this</button></td>
        </tr>
    </table>
</div>

<div class="scrollRow scrollRowOn">
    <table width="100%">
        <tr>
            <td width="25%">Site name: <b>Another site</b></td>
            <td>Created on 3rd Aug 2010</td>
            <td align="right"></td>
        </tr>
    </table>
</div>

</asp:content>

Which is a list of rows, how am I programatically meant to generate these after I have retrieved the SQL rows from the code behind? Do I need to make my own control, or something along those lines?

+3  A: 

Try something along these lines:

    <asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_OnItemDataBound">
    <ItemTemplate>
        <div class='<%# SetClass(Eval("SiteId")) %>'>
            <table width="100%">
              <tr>
                   <td width="25%">Site name: <b><%# Eval("SiteName") %></b></td>
                   <td>Created on <%# DataBinder.Eval(Container.DataItem, "CreateDate", "{0:dd MMM yyyy}")%></td>
                    <td align="right"><button id="btnRevert" runat="server" onclick="doRevert(1)">Revert to this</button></td>
            </tr>
            </table>
          </div>
        </ItemTemplate>
   </asp:Repeater>

In the codebehind Repeater1_OnItemDataBound event you could set the button to be visible or not, depending on whether the item is the current one.

    protected void Repeater1_OnItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        RepeaterItem item = e.Item;
        if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)
        {
            Site site = e.Item.DataItem as Site; //List<Site> is what you are binding to the repeater
            if (site.SiteId == currentSiteId)
            {
                var btn = e.Item.FindControl("btnRevert") as Button;
                if (btn != null)
                {
                    btn.Visible = false;
                }
            }
        }
    } 

CSS Classes for your items can be set like this:

    protected string SetClass(object obj) {
        int siteId;
        if (int.TryParse(obj.ToString(), out siteId)){
            if (siteId == currentSiteId) //currentSiteId determined elsewhere
            {
                return "scrollRow";
            }
        }
        return "scrollRow scrollRowOn";
    }
Daniel Dyson
+1  A: 

I would suggest the repeater control. You can use it something like this:

<asp:Repeater runat="server" id="myRepeater">
<ItemTemplate>
<div class="scrollRow scrollRowOn">
    <table width="100%">
        <tr>
            <td width="25%">Site name: <b><% Eval("SiteName")%></b></td>
            <td>Created on <% Eval("CreatedOn")%></td>
            <td align="right"></td>
        </tr>
    </table>
</div>
</ItemTemplate>
</asp:Repeater>

Then you need to bind your data to it in the Page_Load event:

myRepeater.DataSource = myData;
myRepeater.DataBind();

Where my data is the data that you retrieve from the database.

Giles
Sorry, I edited the wrong answer by mistake. I have rolled back the edit
Daniel Dyson
No Problem Daniel, Nice answer by the way!
Giles
+1  A: 

There are a lot of ways to get to this, of course, but here's one (possibly not the best, but that's subjective anyway):

Assuming C# web forms and ADO.Net, and assuming you need precisely that html, you could loop over the rows in the DataSet and output the html.

DataSet ds = {data set from your sql}
StringBuilder html = new StringBuilder();
foreach (DataRow row in DataSet.Tables[0].Rows) {
   html.Append( string.Format(@"<div class=""scrollRow"">
    <table width=""100%"">
        <tr>
            <td width=""25%"">Site name: <b>{0}</b></td>
            <td>Created on {1}</td>
            <td align="right"><button onclick="doRevert(1)">Revert to this</button></td>
        </tr>
    </table>",row["sitename"], row["createdate"]));
}

You could include the html by having an <asp:Literal> in the page code and setting the Text property.

You could also do it by creating System.Web.UI.WebControls.Table nodes in the code behind and adding TableRows and TableCells to them, using the same loop, and then adding those to the page using. Given what you've given us thus far, you seem to be adding controls to a page with a MasterPage, so you would need to add your tables to the Master's ContentPlaceHolder, which you can find and add controls to like so:

   ContentPlaceHolder ph = (ContentPlaceHolder)this.Master.FindControl( "ContentPlaceHolder1" );

   foreach (DataRow row in DataSet.Tables[0].Rows) {
      Panel pnl = new Panel();
      Table tbl = new Table();
      TableRow tblrow = new TableRow();
      TableCell cell1 = new TableCell();
      cell1.Text = string.Format("Site name: <b>{0}</b>",row["sitename"]);
      row.Cells.Add(cell1);
      tbl.Rows.Add(tblrow);
      pnl.Controls.Add(tbl);
      ph.Controls.Add(pnl);
   }

You can set properties on the TableRows and TableCells, but if you do it this way you will lose some control over the html that's generated, most notably the html ID attributes. You don't seem to be using those, so perhaps that's ok.

cori