Separator Template for table building repeater - c#

I have built repeaters before but dont have much experience manipulating table layout with them. Presently I have a repeater that is populating the data correctly but doing so in one column. I would like it to be 4 columns. I was told using a Separator Template is the best way to do this.
Here is my repeater:
<asp:Repeater ID="myTestRepeater" runat="server"
onitemdatabound="myTest_ItemDataBound">
<Itemtemplate>
<table cellpadding=0 width="100%" valign="top">
<tr>
<td valign="top" width="100%">
<asp:HyperLink ID="lnkTest1" runat="server">
<asp:Image ID="imgTest" runat="server" /></asp:HyperLink>
<asp:HyperLink ID="lnkTest2" runat="server" />
<asp:Label ID="lblCounter" runat="server />
<asp:HyperLink ID="lnkTest3" runat="server"/>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>

The repeater is the most powerful control in the ASP.NET WebForms arsenal; you just need to think sometimes on what is the best way to use it.
For example, you can have a repeater to make multiple rows, and a repeater to make multiple columns. In your situation, if you want your repeater to make multiple columns, you can easily adapt your code:
<asp:Repeater ID="myRepeater" runat="server">
<HeaderTemplate>
<table>
<tr>
</HeaderTemplate>
<ItemTemplate>
<td>
<span>This will be repeated for each element</span>
</td>
</ItemTemplate>
<FooterTemplate>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
It's all in basically how you want to implement your loop.

Seperator Template is used to define the separator between rows. Why can't you use four <td/>s for your four columns?
<Itemtemplate>
<tr>
<td>
...
</td>
<td>
...
</td>
<td>
...
</td>
<td>
...
</td>
</tr>
</ItemTemplate>

try this
<asp:Repeater runat="server" ID="myRepeater">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
Col 1
</td>
<td>
Col 2
</td>
<td>
Col 3
</td>
<td>
Col 4
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table></FooterTemplate>
<SeparatorTemplate>
<tr>
<td colspan="4" style="background-color: #E1E1E1">
</td>
</tr>
</SeparatorTemplate>
</asp:Repeater>

I ended up using a literal as a table break. Then populating that literal based off the mod of my counter
<asp:Repeater ID="myTestRepeater" runat="server"
onitemdatabound="myTest_ItemDataBound">
<Itemtemplate>
<table cellpadding=0 width="100%">
<tr>
<td valign="top" width="25%">
<asp:HyperLink ID="lnkTest1" runat="server">
<asp:Image ID="imgTest" runat="server" /></asp:HyperLink>
<asp:HyperLink ID="lnkTest2" runat="server" />
<asp:Label ID="lblCounter" runat="server />
<asp:HyperLink ID="lnkTest3" runat="server"/>
</td>
<asp:literal id="tablebreak" runat="server"></asp:literal>
</ItemTemplate>
</asp:Repeater>
Then code behind
Literal tableBreak = (Literal)e.Item.FindControl("tablebreak");
if (e.Item.ItemIndex % 4 == 3)
tableBreak.Text = "</tr><tr>";

Here is the way this may be accomplished following the repeater control conventions.
<asp:Repeater id="rptTest" runat="server">
<HeaderTemplate>
<table border="1">
<tr>
</HeaderTemplate>
<ItemTemplate>
<td>
<asp:Literal ID="litContent" runat="server" />
</td>
</ItemTemplate>
<SeparatorTemplate>
</tr>
<tr>
</SeparatorTemplate>
<FooterTemplate>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
The code-behind:
int counter = 0
, columnCount = 3;
rptTest.ItemDataBound += (rpt_sender, rpt_e) => {
if (rpt_e.Item.ItemType == ListItemType.Item || rpt_e.Item.ItemType == ListItemType.AlternatingItem) {
string cellData = (string)rpt_e.Item.DataItem;
Literal litContent = (Literal)rpt_e.Item.FindControl("litContent");
litContent.Text = cellData;
}
else if (rpt_e.Item.ItemType == ListItemType.Separator) {
if (++counter % columnCount != 0)
rpt_e.Item.Visible = false;
}
};
rptTest.DataSource = new string[] { "Cell 1", "Cell 2", "Cell 3", "Cell 4", "Cell 5", "Cell 6", "Cell 7", "Cell 8", "Cell 9", "Cell 10" };
rptTest.DataBind();

Related

How to bind a column header in listview control?

I want to bind a listview control with a datatable , whose column names are not fixed. And i want to display these column names in the page ?
How to achieve this ?
I dont know what exactly you want to do but this is the example of listview that you can set header name whatever you want.
<asp:ListView ID="ListView1" GroupPlaceholderID="group" GroupItemCount="1" ItemPlaceholderID="item" runat="server">
<LayoutTemplate>
<table>
<asp:PlaceHolder runat="server" ID="group"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<GroupTemplate>
<tr>
<asp:PlaceHolder runat="server" ID="item"></asp:PlaceHolder>
</tr>
</GroupTemplate>
<ItemTemplate>
<td>
<table cellpadding="2" cellspacing="0" border="1" style="width: 200px; height: 100px">
<tr>
<td>
<span>
<%# Eval("Id") %>
</span>
</td>
</tr>
<tr>
<td>
Name: <span><%# Eval("Field_name_of_your_DB") %></span><br />
Number: <span><%# Eval("Field_name_of_your_DB") %></span><br />
Date: <span><%# Eval("Field_name_of_your_DB", "{0:MM dd, yyyy}") %></span><br />
Comment: <span><%# Eval("Field_name_of_your_DB") %></span><br />
</td>
</tr>
</table>
</td>
</ItemTemplate>
</asp:ListView>
And, be sure that autogeneratecolumn = false to avoid displaying data twice.

How to databind to a Gridview where column values should appear in sub rows within a main row?

Please can anyone suggest a way to databind a database table to a gridview but in a specific layout where column values should appear in sub rows within a main row, like wise all rows from the database table should list down inside that Gridview.I know the normal way of databinding to a gridview Where it display row data(From Database Table) as columns, but what I want is like below
Gridview is not suitable for this type of format.
If you are okay with repeater, you can do something like this:
And here's a link to MSDN: Repeater Class.
UPDATE: If you want to post each answer selection, you can use option button and group them. You can use questionid as a part of group name and in the code get the question id. Your markup may look like below:
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table border="1">
<tr>
<th colspan="2"></th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# DataBinder.Eval(Container.DataItem, "QuestionId") %> </td>
<td>
<table>
<tr>
<td colspan="4"><%# DataBinder.Eval(Container.DataItem, "Question") %> </td>
</tr>
<tr>
<td>
<asp:RadioButton ID="RadioButton1" runat="server" AutoPostBack="true" Text='<%# DataBinder.Eval(Container.DataItem, "Answer1") %>'
OnCheckedChanged="RadioButton1_CheckedChanged" GroupName='<%# Eval("QuestionId","Grp_{0}") %>' TextAlign="Left" />
</td>
<td><asp:RadioButton ID="RadioButton2" runat="server" AutoPostBack="true" Text='<%# DataBinder.Eval(Container.DataItem, "Answer2") %>'
OnCheckedChanged="RadioButton2_CheckedChanged" GroupName='<%# Eval("QuestionId","Grp_{0}") %>' TextAlign="Left" />
</td>
<td><asp:RadioButton ID="RadioButton3" runat="server" AutoPostBack="true" Text='<%# DataBinder.Eval(Container.DataItem, "Answer3") %>'
OnCheckedChanged="RadioButton3_CheckedChanged" GroupName='<%# Eval("QuestionId","Grp_{0}") %>' TextAlign="Left" />
</td>
<td><asp:RadioButton ID="RadioButton4" runat="server" AutoPostBack="true" Text='<%# DataBinder.Eval(Container.DataItem, "Answer4") %>'
OnCheckedChanged="RadioButton4_CheckedChanged" GroupName='<%# Eval("QuestionId","Grp_{0}") %>' TextAlign="Left" />
</td>
</tr>
</table>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
And in the code:
protected void RadioButton1_CheckedChanged(object sender, EventArgs e)
{
string grpId = ((RadioButton)sender).GroupName;
int questionId = 0;
int.TryParse(grpId.Split('_')[1].ToString(), out questionId);
//Use questionId
}

Repeater control with nested elements TR TD

I want to show my data in the format like below:
<table>
<tr>
<td></td>
<td></td>
<td></td>
...
</tr>
<tr>
<td></td>
<td></td>
<td></td>
...
</tr>
.
.
.
</table>
I am bit confused about how to represent the data.
I am thinking to use the repeater control for this structure. But will it need a nested repeater control or it can be done using the single repeater control?
Can anybody please suggest me the proper way?
Thanks in advance.
Update :: In my case and are not in static order they are fully dynamic.In some cases may have the single but in some case they me be 10-20 in count.I need to show the score for test in those structure.for example:
<table>
<tr>
<td>10</td>
<td>5</td>
<td>30</td>
</tr>
<tr>
<td>40</td>
<td>34</td>
</tr>
.
.
.
<table>
like wise.In simple word when the score record for one user is completed I need to add new record in the new fresh .
Why are you using repeater? It's rather obsolete component. Use ListView instead. It's much more flexible in configuration and manipulation.
Please use solution suggested here by Merrimack
<asp:ListView ID="myListView" runat="server"
DataSourceID="YOURDATASOURCE" GroupItemCount="3">
<LayoutTemplate>
<table>
<tr>
<td>
<table border="0" cellpadding="5">
<asp:PlaceHolder runat="server" ID="groupPlaceHolder"></asp:PlaceHolder>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
<GroupTemplate>
<tr>
<asp:PlaceHolder runat="server" ID="itemPlaceHolder"></asp:PlaceHolder>
</tr>
</GroupTemplate>
<ItemTemplate>
<td>
<%# Eval("FullName") %>
</td>
</ItemTemplate>
</asp:ListView>
One solution from Old Classic way is nested loop
<table>
<% for(int loop1 = 0; loop1 <= condition1 ; loop1++){
System.Console.WriteLine("<tr>");
for(int loop2 = 0; loop2 <= condition2 ; loop2++){
System.Console.WriteLine("<td>");
System.Console.WriteLine("Your Data");
System.Console.WriteLine("</td>");
}
System.Console.WriteLine("</tr>");
} %>
</table>
You could make a Repeater like this
<asp:Repeater ID="rptMyRepeater" runat="server" >
<HeaderTemplate>
<table>
<th>
<td>
Header 1
</td>
<td>
Header 2
</td>
</th>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:HiddenField runat="server" ID="hfHolderId" Value='<%# DataBinder.Eval(Container.DataItem, "HolderId") %>' />
<asp:TextBox runat="server" ID="tbText1" Text='<%# DataBinder.Eval(Container.DataItem, "Text1") %>' />
</td>
<td>
<asp:TextBox runat="server" ID="tbText2" Text='<%# DataBinder.Eval(Container.DataItem, "Text2") %>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Then have a class to hold your data
public class MyHolder()
{
public string HolderId {get;set;}
public string Text1 {get;set;}
public string Text2 {get;set;}
}
Then make a list of these and bind them to your Repeater
List<MyHolder> myHolderList = new List<MyHolder>();
myHolderList.Add(new MyHolder {1, "hi", "hello"});
//Add a few of these
rptrptMyRepeater.DataSource = myHolderList;
rptMyRepeater.DataBind();
All this was just outta my head so there my be syntax errors in there
I finally done this with the dynamic table in asp.net.Like RDSAGAR did,but by code behind.Thanks for all your support.

How to add caption and sum a column?

i want give caption DATE,PRICE1, PRICE2 and i also show sum of price1, price2 in the footer. how can i do this?
<asp:Repeater ID="rptCari" runat="server">
<ItemTemplate>
<div>
<tr>
<td>
<asp:Label runat="server" ID="lblBelgeTarihi"><%#(Eval("DATE","{0:d}"))%></asp:Label>
</td>
<td>
</td>
<td>
<asp:Label runat="server" ID="lblAlacakTutar"><%#ValidationHelper.FormatPrice(ValidationHelper.GetDecimal(Eval("PRICE1"), 0))%></asp:Label>
</td>
<td>
</td>
<td>
<asp:Label runat="server" ID="lblBorcTutar"><%#ValidationHelper.FormatPrice(ValidationHelper.GetDecimal(Eval("PRICE2"), 0))%></asp:Label>
</td>
</tr>
</div>
</ItemTemplate>
</asp:Repeater>
You've HeaderTemplate and FooterTemplate as child elements of Repeater.

Table display issue

I got a table with 2 nested tables inside that display my two repeaters. My repeaters display Home and office addresses respectively. The problem is that whenever I add a new record in one repeater, the other repeater table's display gets messed up. Like if I add a record in rpt1 , then table for rpt1 moves up and table for rpt2 goes down..ie the headers do not display in one single line . They move up and down when records are added or deleted. WHat I want is these headers to be fixed so if I add new records or delete records, the headings of both repeaters display on the same line...How do I fix this ? Hope its not confusing.
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td width="50%">
<asp:Panel ID="pnlAddAddress" runat="server">
<asp:Repeater ID="rpt1" OnItemCommand="rpt1_ItemCommand" runat="server" OnItemDataBound="rpt1_OnItemDataBound">
<HeaderTemplate>
<table width="99%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td colspan="5" class="linegrey">
</td>
</tr>
<tr class="lgrey">
<td>
Address1
</td>
<td>
City
</td>
<td>
State
</td>
<td>
IsDefault
</td>
<td>
Actions
</td>
</tr>
<tr>
<td colspan="5" class="dots">
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="lnkAddressB" runat="server" Text='<%# Eval("Address1")%>' CommandName="DisplayAddressB" CommandArgument='<%#Eval("AddID") %>' CausesValidation=false></asp:LinkButton>
</td>
<td>
<%# Eval("City")%>
</td>
<td>
<%# Eval("State")%>
</td>
<td>
<%-- Visible='<%# Eval("IsDefault")%>'--%>
<asp:LinkButton ID="lnkDefaultB" Text="Set as Default" CommandName="SetDefaultB" runat="server" CommandArgument='<%# Eval("AddID") + "," + Eval("IsB") %>'
CausesValidation="false" Visible='<%# Eval("IsDefault")%>'></asp:LinkButton>
<asp:Label ID="labelDefaultB" Text="Yes" runat="server" Visible='<%# Eval("IsDefault")%>'></asp:Label>
</td>
<td>
<asp:ImageButton ID="lnkAdd" CommandArgument='<%#Eval("AddID") %>'
CausesValidation="false" CommandName="Edit" runat="server" ImageUrl="~/images/Edit.gif" Width="14" Height="14" ToolTip="Edit"></asp:ImageButton>
<asp:ImageButton ID="lnkDel" Text="Delete" CommandArgument='<%#Eval("AddID") %>'
CausesValidation="false" CommandName="Delete" runat="server" ImageUrl="~/images/Delete.gif" Width="14" Height="14" ToolTip="Delete"></asp:ImageButton>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</asp:Panel>
</td>
<td>
<asp:Panel ID="pnlSping" runat="server">
<asp:Repeater ID="rpt12" OnItemCommand="rpt12_ItemCommand" runat="server" OnItemDataBound="rptSpping_OnItemDataBound">
<HeaderTemplate>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td colspan="5" class="linegrey">
</td>
</tr>
<tr class="lgrey">
<td>
Address1
</td>
<td>
City
</td>
<td>
State
</td>
<td>
IsDefault
</td>
<td>
Actions
</td>
</tr>
<tr>
<td colspan="5" class="dots">
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:LinkButton ID="lnkAddressS" runat="server" Text='<%# Eval("Address1")%>' CommandArgument='<%#Eval("AddID") %>' CommandName="DisplayAddressS" CausesValidation="false"></asp:LinkButton>
</td>
<td>
<%# Eval("City")%>
</td>
<td>
<%# Eval("State")%>
</td>
<td>
<asp:LinkButton ID="lnkDefaultS" Text="Set as Default" CommandName="SetDefaultS" runat="server" Visible=true CommandArgument='<%# Eval("AddID") + "," + Eval("IsS") %>'
CausesValidation="false"></asp:LinkButton>
<asp:Label ID="labelDefaultS" Text="Yes" runat="server" Visible=true></asp:Label>
</td>
<td>
<asp:ImageButton ID="lnkAdd" Text="Edit" CommandArgument='<%#Eval("AddID") %>'
CausesValidation="false" CommandName="Edit" runat="server" ImageUrl="~/images/Edit.gif" Width="14" Height="14" ToolTip="Edit"></asp:ImageButton>
<asp:ImageButton ID="lnkDel" Text="Delete" CommandArgument='<%#Eval("AddID") %>'
CausesValidation="false" CommandName="Delete" runat="server" ImageUrl="~/images/Delete.gif" Width="14" Height="14" ToolTip="Delete"></asp:ImageButton>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</asp:Panel>
</td>
</tr>
</table>
Use css attribute valign and set its value to top like this <td width="50%" valign="top">.
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td width="50%" valign="top">
<asp:Panel ID="pnlAddAddress" runat="server">
......
</asp:Panel>
</td>
<td valign="top">
<asp:Panel ID="pnlSping" runat="server">
......
</asp:Panel>
</td>
</tr>
</table>
For headers look to use the <th> element, this will keep them at the top of the table.
Put the <table> tags you do have outside your repeater controls, make sure the repeater only renders a single row and the same for the header.
Unless you have good reason consider just wrapping the two tables in <div> tags as nested tables really don't work ideally for layout.

Categories