I have a set of items coming from the database. Their number may vary. I have bound them in a repeater. Now my following example will explain what I want:
I have 11 items coming from database, I want them to be grouped in terms of 5 items per row.
- 1st row: 5 items.
- 2nd row: 5 items.
- 3rd row: 1 item.
Currently, I am just binding them in a repeater. How do I do this?
Yes. It is possible:
<asp:Repeater ID="rptItems" runat="server">
<ItemTemplate>
<asp:Literal runat="server" Text='<%# Eval("Value") %>'></asp:Literal>
<div style="clear: both" runat="server" Visible="<%# (Container.ItemIndex+1) % 5 == 0 %>"></div>
</ItemTemplate>
</asp:Repeater>
It produces following results for the sequence of numbers:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
if you can use ListView, then you can use GroupItemCount . some thing like this MSDN Example
<asp:ListView ID="ContactsListView"
DataSourceID="yourDatasource"
GroupItemCount="5"
runat="server">
<LayoutTemplate>
<table id="tblContacts" runat="server" cellspacing="0" cellpadding="2">
<tr runat="server" id="groupPlaceholder" />
</table>
</LayoutTemplate>
<ItemTemplate>
<div> your Items here </div>
</ItemTemplate>
<GroupTemplate>
<tr runat="server" id="ContactsRow" style="background-color: #FFFFFF">
<td runat="server" id="itemPlaceholder" />
</tr>
</GroupTemplate>
<ItemSeparatorTemplate>
<td runat="server" style="border-right: 1px solid #00C0C0"> </td>
</ItemSeparatorTemplate>
</asp:ListView>
If you want to stick with a Repeater, I can think of two approaches.
Firstly, you could stick with a flat list of items and make the repeater insert a "new line" after each 5th item. You should be able to do this in the <ItemTemplate>
with a block like
<% if ((Container.DataItemIndex % 5) == 4) { %>
</div>
<div>
<% } %>
which honestly isn't very nice.
Alternatively, you could use MoreLINQ's Batch method to batch your items up into IEnumerable
s of 5, and then use two nested repeaters to render them. Set the outer repeater to wrap the inner repeater in <div>
tags, and set the inner repeater's DataSource='<%# Container.DataItem %>'
. This should result in much cleaner markup.
You can try below, I mistakenly said ListView, actually I meant DataList
<asp:DataList ID="DataList1" runat="server" RepeatColumns="5"
RepeatDirection="Horizontal" RepeatLayout="Flow">
<ItemTemplate >
<%--Your Item Data goes here--%>
</ItemTemplate>
</asp:DataList>
You may use nested Data controls (i.e Repeater
) and also handle the OnItemDataBound
event to bind the inner Repeater.
Sample Data Source component:
public class Item
{
public int ID { get; set; }
public string Name { get; set; }
public static List<List<Item>> getItems()
{
List<Item> list = new List<Item>()
{
new Item(){ ID=11, Name="A"},
new Item(){ ID=12, Name="B"},
new Item(){ ID=13, Name="C"},
new Item(){ ID=14, Name="D"},
new Item(){ ID=15, Name="E"},
};
/* Split the list as per specified size */
int size = 2;
var lists = Enumerable.Range(0, (list.Count + size - 1) / size)
.Select(index => list.GetRange(index * size,
Math.Min(size, list.Count - index * size)))
.ToList();
return lists;
}
}
Markup (.aspx)
<asp:Repeater ID="outerRepeater"
runat="server" onitemdatabound="outerRepeater_ItemDataBound"
>
<ItemTemplate>
<p>
Row
</p>
<asp:Repeater ID="innerRepeater"
runat="server">
<ItemTemplate>
<asp:Literal ID="literal1" runat="server" Text='<%# Eval("ID") %>' />
<asp:Literal ID="literal2" runat="server" Text='<%# Eval("Name") %>' />
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Code-behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
outerRepeater.DataSource = Item.getItems();
outerRepeater.DataBind();
}
}
protected void outerRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater repeater = e.Item.FindControl("innerRepeater") as Repeater;
repeater.DataSource = Item.getItems()[e.Item.ItemIndex];
repeater.DataBind();
}
<asp:Repeater ID="Repeater1" runat="server"
OnItemDataBound="Repeater1_databinding">
<HeaderTemplate>
<table id="masterDataTable" class="reportTable list issues" width="100%">
<thead>
<tr>
<asp:Literal ID="literalHeader" runat="server"></asp:Literal>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<asp:Literal ID="literals" runat="server"></asp:Literal>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody> </table>
</FooterTemplate>
</asp:Repeater>
<input id="hdnColumnName" runat="server" clientidmode="Static" type="hidden" />
<input id="hdnColumnOrder" runat="server" clientidmode="Static" type="hidden" />
// javascript Function
<script type="text/javascript">
$(document).ready(function () {
$('#ddlReport').removeClass('required');
$('.sort').click(function () {
$('#hdnColumnName').val($(this).text());
$('#hdnColumnOrder').val($(this).attr('class'));
$(this).toggleClass("desc asc");
$("#lnkSort").click();
});
});
</script>
// Bind repeater
DataTable dt = objReport.GetCustomRecord();
fn = new List<string>();
for (int i = 0; i < dt.Columns.Count; i++)
{
if (dt.Columns[i].ColumnName != "Maxcount" )
{
fn.Add(dt.Columns[i].ColumnName);
}
}
Repeater1.DataSource = dt;
Repeater1.DataBind();
protected void Repeater1_databinding(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
if (e.Item.FindControl("literalHeader") != null)
{
StringBuilder sb = new StringBuilder();
Literal li = e.Item.FindControl("literalHeader") as Literal;
fieldName().ForEach(delegate(string fn)
{
if (hdnColumnName.Value != fn.ToString())
{
sb.Append("<th width=\"10%\"> <a id=\"btnCustomerName\" class=\"sort desc\" onclick=\"btnSorts_onclick()\" style=\"cursor:pointer;text-decoration: none !important;\" >"
+ fn.ToString() + "</a></th>");
}
else
{
if (hdnColumnOrder.Value == "sort asc")
sb.Append("<th width=\"10%\"> <a id=\"btnCustomerName\" class=\"sort desc\" onclick=\"btnSorts_onclick()\" style=\"cursor:pointer;text-decoration: none !important;\" >"
+ fn.ToString() + "</a></th>");
else
sb.Append("<th width=\"10%\"> <a id=\"btnCustomerName\" class=\"sort asc\" onclick=\"btnSorts_onclick()\" style=\"cursor:pointer;text-decoration: none !important;\">"
+ fn.ToString() + "</a></th>");
}
});
li.Text = sb.ToString();
}
}
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
if (e.Item.FindControl("literals") != null)
{
DataRowView drv = (DataRowView)e.Item.DataItem;
Literal li = e.Item.FindControl("literals") as Literal;
StringBuilder sb = new StringBuilder();
fieldName().ForEach(delegate(string fn)
{
sb.Append("<td>" + drv[fn.ToString()] + "</td>");
});
li.Text = sb.ToString();
}
}
}