ASP Repeater - ItemTemplate - asp.net

Good afternoon.
I have a Repeater with a ItemTemplate that prints one column with data.
<asp:Repeater id="OtherProductsRepeater" runat="server">
<ItemTemplate>
(...data...)
</ItemTemplate>
</asp:Repeater>
How can i modify the code to instead of one column create three columns to show the data?
Thanks in advance.

Edited to show using repeater to make a three column layout
<table>
<asp:Repeater id="OtherProductsRepeater" OnItemCreated="OtherProductsRepeater_ItemCreated" runat="server">
<ItemTemplate>
<asp:PlaceHolder id="row_end" visible="<%# _showRowEnd %>" runat="server">
</tr>
</asp:PlaceHolder>
<asp:PlaceHolder id="row_start" visible="<%# _showRowStart %>" runat="server">
<tr>
</asp:PlaceHolder>
<td>(data)</td>
<td>(data)</td>
<td>(data)</td>
</ItemTemplate>
</asp:Repeater>
</tr> <%-- close final row --%>
</table>
in your code, you need these page level members:
private int _rowCounter = 0;
protected bool _showRowEnd;
protected bool _showRowStart;
and the event handler:
protected void OtherProductsRepeater_ItemCreated(Object Sender, RepeaterItemEventArgs e) {
if (_rowCounter == 0) { // first row
_showRowStart = true;
_showRowEnd = false;
_rowCounter = 1;
}
else if (_rowCounter == 3) {
_showRowStart = true;
_showRowEnd = true;
_rowCounter = 1;
}
else {
_showRowStart = false;
_showRowEnd = false;
_rowCounter += 1;
}
}
Another thought - if you are talking about newspaper-style columns, where the content flows from the bottom of one column to the top of the next, use a DataList control instead of a repeater.

be sure to encapsulate all the mark up in the single control in case visible=false, or item.count=0
<asp:Repeater id="OtherProductsRepeater" runat="server">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>(data)</td>
<td>(data)</td>
<td>(data)</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>

If you're using ASP.net 3.5 or higher you should use ListView and the GroupTemplate.
For example code, See...
https://web.archive.org/web/20211020150712/https://www.4guysfromrolla.com/articles/010208-1.aspx

Related

Binding ListView Field to Value in Code-Behind

I'm displaying fields from a DB call in a ListView. I had to re-code my database query because of an issue with repeating groups. I also didn't want to have to deal with nested ListViews. So now I am trying to set the header to the value of radio button list selection. I was trying to write a custom method to return that value but could not remember the syntax.
How can I set the header in the LayoutTemplate from the code-behind so that it doesn't repeat?
<LayoutTemplate>
<div class="resultsGrid">
<strong><%# GetHeader() %></strong>
<asp:PlaceHolder runat="server" ID="resultsPlaceHolder">
</asp:PlaceHolder>
</div>
</LayoutTemplate>
<ItemTemplate>
// rest of data
</ItemTemplate>
I was able to solve this as follows:
<asp:ListView ID="resultsList" ItemPlaceholderID="resultsPlaceHolder"
OnItemCreated="ResultsList_ItemCreated" runat="server">
<LayoutTemplate>
<div class="resultsGrid">
<strong><asp:Label ID="headerLabel" runat="server"></asp:Label></strong>
<asp:PlaceHolder runat="server" ID="resultsPlaceHolder">
</asp:PlaceHolder>
</div>
</LayoutTemplate>
<ItemTemplate>
// rest of data
</ItemTemplate>
</asp:ListView>
And in the code-behind:
protected void ResultsList_ItemCreated(object sender, ListViewItemEventArgs e)
{
if (e.Item is ListViewItem)
{
Label tempLabel = resultsList.FindControl("headerLabel") as Label;
tempLabel.Text = ViewState["ParkName"].ToString();
}
}

Hide EmptyDataTemplate but leave header visible

I have an EmptyDataTemplate on my ASP.NET webform which allows users to add a record to the database. Depending on the permissions of the user, this EmptyDataTemplate needs to be visible and hidden if no data is found (I have this working!)
For example, my user has Read Access only. When they search a specific criteria, no results are displayed they cannot see the EmptyDataTemplate. However, if they search a criteria, and there is data, data is displayed WITHOUT the headers.
Can someone please help explain why this is happening and if there's a way around it?
The headers are HeaderText on TemplateFields.
I'm hoping it's a general trick.
Thank you in advance for your help!
Please note, it's the HeaderText in the TemplateFields I want to display- not the in the emptyDataTemplate as they'll head up the columns of data that match the search criteria.
edit: code added as requested
For hiding the EmptyDataTemplate:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
Control control = null;
control = GridView1.Controls[0].Controls[0];
if (userManagement.getMIFReadWriteAccess() == "Read")
{
control.Visible = false;
Export_All.Visible = true;
}
else if (userManagement.getMIFReadWriteAccess() == "Write")
{
control.Visible = true;
Export_All.Visible = true;
}
}
in markup for the header text (i've only shown one column but the markup is the same for all of them)
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="lbl_Index" runat="server" Text='<%#Eval("id") %>'></asp:Label>
<asp:Label ID="lbl_ID" runat="server" Text="" Visible="false"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
EmptyDataTemplate:
<EmptyDataTemplate>
<div id="emptyData" runat="server">
<tr>
<th></th>
<th>Serial Number</th>
<th>Comments</th>
<th>Review Date</th>
<th>Approved By</th>
</tr>
<tr>
<td>
<asp:Button runat="server" ID="btInsert" Text="In" OnClick="Add" CommandName="EmptyDataTemplate" Class="Button" OnClientClick="return confirm('You are about to confirm this action. Please confirm this action by clicking OK. If you do not wish to do this, please select Cancel.');" />
<br />
<asp:Button runat="server" ID="btInsertOut" Text="Out" OnClick="AddOut" CommandName="EmptyDataTemplate" Class="Button" OnClientClick="return confirm('You are about to confirm this action. Please confirm this action by clicking OK. If you do not wish to do this, please select Cancel.');" />
</td>
<td>
<asp:TextBox runat="server" ID="tb_Serial_Number" CssClass="text"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="tb_comments" Width="100%" MaxLength="50" runat="server" placeholder="max 50 characters"/>
</td>
<td>
<asp:TextBox ID="tb_reviewDate" runat="server" DataFormatString="{0:dd/mm/yyyy}" Text='<%#Eval("review_by") %>'></asp:TextBox>
</td>
<td><asp:DropDownList ID="tb_approved_by" runat="server">
</asp:DropDownList> </td>
</tr>
</div>
</EmptyDataTemplate>
After trial and error, I found that programatically adding a header row in C# did the trick. Probably not the best way of doing it, but it worked.
Code is as follows:
#region show the emptyDataTemplate depending on user rights
Control control = null;
control = GridView1.Controls[0].Controls[0];
if (userManagement.getMIFReadWriteAccess() == "Read")
{
control.Visible = false;
GridViewRow HeaderRow = new GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableCell HeaderCell2 = new TableCell();
HeaderCell2.Text = "Country";
HeaderCell2.ColumnSpan = 1;
HeaderRow.Cells.Add(HeaderCell2);
//Repeat the above for every column of data you have!
GridView1.Controls[0].Controls.AddAt(0, HeaderRow);

Checkbox server/client events

I have a checkbox in repeater control.
on changing it's bit value, it should prompt the alert message like do u wish to delete?
and if yes is selected, the onselectedchange server event should be fired.
Right now. on clicking the checkbox i am using onclick event to fire the prompt but it is not able to fire the server event.
here is my code
<script language="javascript" type="text/javascript">
function CheckedChange() {
if (confirm('Are you sure you want to delete?'))
return true;
else
return false;
}
</script>
<asp:Repeater ID="repQuestion" runat="server" onitemcommand="repQuestion_ItemCommand" onitemdatabound="repQuestion_ItemDataBound">
<ItemTemplate>
<table width="100%" cellspacing="0" cellpadding="0">
<tr>
<td>
<asp:CheckBox onclick="return CheckedChange();" ID="delete" runat="server" Checked='<%#DataBinder.Eval(Container.DataItem, "IsDeleted")%>' OnCheckedChanged="chkdelete_Click" />
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
Work around this snippet.
The Repeater.
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<table>
<tr>
<td><%# Eval("Index") %></td>
<td>
<asp:CheckBox ID="delete" runat="server"
AutoPostBack="true"
Checked='<%# Convert.ToBoolean(Eval("IsDeleted")) %>'
Enabled='<%# !Convert.ToBoolean(Eval("IsDeleted")) %>'
OnCheckedChanged="chkdelete_Click"
onclick="javascript:return CheckedChange(this)"/>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
JavaScript
function CheckedChange(objCheckBox) {
if (confirm('Are you sure you want to delete?')) {
__doPostBack("'" + objCheckBox.id + "'", '');
return true;
}
else {
objCheckBox.checked = false;
return false;
}
}
Page_Load Event
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
//bind gridview here
DataTable dataTable = new DataTable
{
Columns = { "Index", { "IsDeleted", typeof(bool) } }
};
bool temp = true;
for (var i = 0; i < 6; i++)
{
dataTable.Rows.Add((i + 1).ToString(), temp);
temp = !temp;
}
Repeater1.DataSource = dataTable;
Repeater1.DataBind();
}
}
catch (Exception exception)
{
//Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
}
}
Well, I don't personally like exposing the __doPostBack but this seems to be the only way in this case.
On an unrelated side note, if you are showing deleted items, its better to show them disabled.
Try by passing the UniqueID (that is the name of the Checkbox).
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<table>
<tr>
<td><%# Eval("Index") %></td>
<td>
<asp:CheckBox ID="delete" runat="server"
AutoPostBack="true"
Checked='<%# Convert.ToBoolean(Eval("IsDeleted")) %>'
Enabled='<%# !Convert.ToBoolean(Eval("IsDeleted")) %>'
OnCheckedChanged="chkdelete_Click"
onclick="javascript:return CheckedChange(this)"/>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
JavaScript
function CheckedChange(objCheckBox) {
if (confirm('Are you sure you want to delete?')) {
__doPostBack("'" + objCheckBox.name + "'", '');
return true;
}
else {
objCheckBox.checked = false;
return false;
}
}
Try this
function confirmUser(checkBox)
{
if(checkBox.childNodes[0].checked === false){
alert('Your alert message');
}
}
<asp:Repeater ID="rptSelecteduserRoles" runat="server" OnItemDataBound="rptSelecteduserRoles_OnItemDataBound">
<ItemTemplate>
<asp:CheckBox ID="chkBox" CssClass="fieldLabel" AutoPostBack="False" onchange="confirmUser(this)"runat="server" Text='<%# Eval("Name") %>' />
</ItemTemplate>
</asp:Repeater>

How to get item click event in asp.net repeater control?

I am using a repeater control to show some data on my page.
The repeater item template has an image and a label field.
I want that when i click the image , I get an event containing the id field of my data item.
How can I achieve this ?
Actually when I click the image i want to go to another page and want to show detailed information of my data item, in repeater i m just showing short information.
My repeater looks like this:
<asp:Repeater ID="itemRepeater" runat="server" OnItemCreated="itemRepeater_ItemCreated" >
<ItemTemplate>
<tr>
<td colspan="2">
<asp:Image ID="phImage" runat="server" ImageUrl='<%#"~/ImageHandler.ashx?id=" + DataBinder.Eval(Container.DataItem, "PhotoID")%>' />
</td>
<td>
<asp:Label ID="lblImageName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
I want to get PhotoID in the event when i click the image.
My photo class looks like this:
public class PhotoDC
{
public byte[] ImagebyteArray { get; set; }
public string Name { get; set; }
public int PhotoID { get; set; }
}
I have been doing winform programming just started web, maybe it is easy but i m struggling to find a solution.
I somehow managed to show hand cursor when i hover the image though.
Try this:
<asp:Repeater ID="itemRepeater" runat="server" OnItemCreated="itemRepeater_ItemCreated" >
<ItemTemplate>
<tr>
<td colspan="2">
<asp:ImageButton ID="phImage" runat="server" ImageUrl='<%#"~/ImageHandler.ashx?id=" + DataBinder.Eval(Container.DataItem, "PhotoID")%>' OnCommand="Image_Click" CommandName="ImageClick" CommandArgument='<%# Eval("PhotoID") %>' />
</td>
<td>
<asp:Label ID="lblImageName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
protected void Image_Click(object sender, CommandEventArgs e)
{
if (e.CommandName == "ImageClick"){
//e.CommandArgument --> photoid value
//Do something
}
}
You can use ItemCommand of repeater control
like this -
protected void itemRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
if (e.CommandName == "img_Click") // check command is cmd_delete
{
// get you required value
int CustomerID = Convert.ToInt32(e.CommandArgument);
//Write some code for what you need
}
}
}
Personally I think the simplest way to handle something like this is to simply use the ItemTemplate to generate a regular html link, rather than do any thing in the code-behind. Something like this:
<asp:Repeater ID="itemRepeater" runat="server" OnItemCreated="itemRepeater_ItemCreated" >
<ItemTemplate>
<tr>
<td colspan="2">
<a href="/Details.aspx?id=<%=DataBinder.Eval(Container.DataItem, "PhotoID")%>">
<asp:Image ID="phImage" runat="server" ImageUrl='<%#"~/ImageHandler.ashx?id=" + DataBinder.Eval(Container.DataItem, "PhotoID")%>' />
</a>
</td>
<td>
<asp:Label ID="lblImageName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>' />
</td>
</tr>
</ItemTemplate>
I know this isn't strictly the question you asked, but IMHO it's the best approach to accomplish the task.

Render empty repeater

When Repeater contains no items it's not get rendered in HTML at all, even HeaderTemplate or FooterTemplate. I need to manipulate it on client-side even if it's empty.
Is there any way to always render Repeater in HTML?
In the <FooterTemplate>, add a Label with some empty data text and set its visible property to false.
<FooterTemplate>
<table>
<tr>
<td>
<asp:Label ID="lblEmptyData"
Text="No Data To Display" runat="server" Visible="false">
</asp:Label>
</td>
</tr>
</table>
</FooterTemplate>
Now check the the data while binding repeater, if no rows return then make label visible otherwise no action.
More details here.
as #Saurabh said, use <FooterTemplate> add a Label with specifying your message in the Text property and set its visible property to false like this:
<FooterTemplate>
<%-- Label used for showing Error Message --%>
<asp:Label ID="ErrorMessage" runat="server" Text="Sorry!!" Visible="false">
</asp:Label>
</FooterTemplate>
Then in the code-behind use the following logic; if there is no data, show the message, otherwise, show the data as following:
protected void Repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Repeater rpt = sender as Repeater; // Get the Repeater control object.
// If the Repeater contains no data.
if (rpt != null && rpt.Items.Count < 1)
{
if (e.Item.ItemType == ListItemType.Footer)
{
// Show the Error Label (if no data is present).
Label ErrorMessage = e.Item.FindControl("ErrorMessage") as Label;
if (ErrorMessage != null)
{
ErrorMessage.Visible = true;
}
}
}
}
<asp:Repeater ID="rptList" runat="server" DataSourceID="odsList">
...
<FooterTemplate>
<%if (rptList.Items.Count == 0)
{ %>
**Your message**
<%} %>
</FooterTemplate>
</asp:Repeater>
Try this
protected bool IsDataEmpty
{
get
{
ICollection list = Repeater1.DataSource as ICollection;
return list.Count == 0 ? true : false;
}
}
In Markup :
<table width="80%">
<tr runat="server"
visible='<%# IsDataEmpty %>'>
<td>
There is no data to display
</td>
</tr>
for step by step follow the link :Link

Resources