How to get updated Textbox value from Repeater? - c#

I have a repeater control as listed below. It has a textbox control. When a save button is clicked, I need to get the updated text from the textbox. I have the following code; but it gives me the old value when I take the textbox text.
How can we get the updated text?
Code Behind
protected void Save_Click(object sender, EventArgs e)
{
foreach (RepeaterItem item in repReports.Items )
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem )
{
string updatedEmail = ((TextBox)item.Controls[5]).Text;
string originalEmail = ((HiddenField)item.Controls[7]).Value;
}
}
}
Control Markup
<div class="repeaterTableBorder">
<asp:Repeater ID="repReports" runat="server">
<ItemTemplate>
<div id="repeaterIdentifier" class="repeaterIdentifier">
<div class="reportTitle">
<%# Eval("ReportName") + ":"%>
<asp:HiddenField ID="hdnLastChangeTime" runat="server" Value= '<%# ((DateTime)Eval("RecordSelectionTime")).ToString("MM/dd/yyyy hh:mm:ss.fff tt")%>' />
<asp:HiddenField ID="hdnReportID" runat="server" Value='<%# Eval("ReportTypeCode")%>' />
</div>
<div class="reportFrequency">
<%# " Frequency - Weekly" %>
</div>
</div>
<div class="reportContent">
<div class="repeaterLine">
<asp:TextBox ID="txtEmailRecipients" runat="server" class="textEdit"
Text='<%# Eval("ExistingRecipients") %>'
TextMode="MultiLine"></asp:TextBox>
<asp:HiddenField ID="hdnOriginalRecipients" runat="server" Value='<%# Eval("ExistingRecipients")%>' />
</div>
</div>
</ItemTemplate>
</asp:Repeater>
</div>

I assume that you are binding the Repeater to it's DataSource also on postbacks. You should do that only if(!IsPostBack). Otherwise the values will be overwritten.
protected void Page_Load(Object sender, EventArgs e)
{
if(!IsPostBack)
{
// databinding code here
}
}

Related

access items in repeater

I have a repeater and I am trying to access labels inside it. Here is my method:
protected void ButtonlarıTemizle()
{
int n = 0;
foreach (RepeaterItem item in Repeater1.Items)
{
n++;
Label lbl = item.FindControl("lblApproved") as Label;
Button btn = item.FindControl("btnAssignApproved") as Button;
if (lbl.Text.Equals("Satışa Dönmüştür"))
{
btn.Visible = false;
lbl.ForeColor = System.Drawing.Color.Blue;
}
}
Response.Write("<script lang='JavaScript'>alert('"+n+"');</script>");
}
I can access inside repeater but here is the problem: I can't access the last item of repeater. I put that 'n' variable to control how many times I turn inside foreach loop and I see that n always gives -1 of item numbers. For example if I have 3 items in repeater, n is 2, if there is 1 item in repeater, n is 0. What am I doing wrong in here ?
Edit: I am writing my .aspx page since it asked
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="EntityDataSourceTeklifler" OnItemCommand="Repeater1_ItemCommand">
<ItemTemplate>
<div class="panel panel-primary">
<div class="panel-body">
<strong>Teklif No.</strong> <%#Eval("TeklifId") %><br />
<strong>Teklif Tarihi:</strong> <%#Eval("TeklifTarih") %><br />
<strong>Teklifi Hazırlayan:</strong> <%#Eval("Name") %> <%#Eval("Surname") %><br />
<strong>Firma Adı:</strong> <%#Eval("FirmaAdi") %><br />
<strong>Ürünler:</strong><br />
<%#Eval("TeklifSiparis") %>
<strong>Genel Toplam:</strong> <%#Eval("TeklifTutar") %>$<br />
<strong>Not:</strong><br />
<%#Eval("TeklifNot") %><br />
<strong>Teklif Durumu:</strong> <asp:Label ForeColor="Red" ID="lblApproved" runat="server" Text='<%# CheckIfApproved(Convert.ToBoolean(Eval("Approved"))) %>'></asp:Label><br /><br />
<asp:Button ID="btnAssignApproved" runat="server" Text="Satışa Döndü Olarak İşaretle" CssClass="btn btn-primary" CommandName="Done" CommandArgument='<%# Eval("TeklifId") %>' />
</div>
</div>
</ItemTemplate>
</asp:Repeater>
I am not sure why you explicitly calling a different method but what you are doing can be easily done in ItemDataBound event of repeater control:-
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound"
Then handler it like this:-
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item)
{
Label lbl = e.Item.FindControl("lblApproved") as Label;
Button btn = e.Item.FindControl("btnAssignApproved") as Button;
if (lbl.Text.Equals("Satışa Dönmüştür"))
{
btn.Visible = false;
lbl.ForeColor = System.Drawing.Color.Blue;
}
}
}
Please note there is no need to do any loop on your repeater items. Repeater ItemDataBound event will fire for each item when it is bounded. Also, if you want to have a count simply declare a variable outside this method and increment it inside this event.

Get a value from Repeater in code-behind

<asp:Repeater ID="Repeater1" runat="server" DataSourceID="EntityDataSourceTeklifler">
<ItemTemplate>
<div class="panel panel-primary">
<div class="panel-body">
<strong>Teklif Kodu:</strong> <%#Eval("TeklifId") %><br />
<strong>Teklif Tarihi:</strong> <%#Eval("TeklifTarih") %><br />
<strong>Teklifi Hazırlayan:</strong> <%#Eval("Name") %> <%#Eval("Surname") %><br />
<strong>Firma Adı:</strong> <%#Eval("FirmaAdi") %><br />
<strong>Sipariş:</strong> <%#Eval("FUrunId") %><br />
<strong>Teklif Tutarı:</strong> <%#Eval("TeklifTutar") %><br />
</div>
</div>
</ItemTemplate>
</asp:Repeater>
As you can see I have a Repeater and it displays my data without a problem. I need to access TeklifIds in code-behind. I am going to make something like:
if(TeklifId == 1)
{
//do something
}
else if(TeklifId == 2)
{
//do something else
}
And to do this, I need to get all TeklifId while it is adding to the Repeater.
Ideally you should include the data withing some ASP.NET controls like Label, Textbox control within ItemTemplate tag because it is easy to work with them. But I am not sure why you are adding the normal html tags directly.
Anyways, to find the value you will have to find it within the ItemDataBound control of repeater control but for that you will have to make the strong tag a server control by adding runat="server" attrribute like this:-
<strong id="TeklifId" runat="server">Teklif Kodu:</strong> <%#Eval("TeklifId") %>
Then, add the ItemDataBound event in your repeatre control like this:-
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand"
Finally in the code behind you can find the value like this:-
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem ||
e.Item.ItemType == ListItemType.Item)
{
HtmlGenericControl TeklifId = e.Item.FindControl("TeklifId") as HtmlGenericControl;
string TeklifId = TeklifId.InnerText; //value here
}
}
Place TeklifId in a Label control so that you can use ID and FindControl to get the values like this:
<asp:Label ID="TeklifId" runat="server" Text='<%#Eval("TeklifId") %>'></asp:Label>
And then:
foreach (RepeaterItem item in Repeater1.Items)
{
var TeklifId = (Label)item.FindControl("TeklifId");
if (TeklifId == 1)
{
//do something
}
}
Repeater Code :
<td>
<span runat="server" id="lbBranchname" style="font-style:italic;"><%# Eval("branchname")%></span>
</td>
Code behind : rptBranch_ItemCommand
HtmlGenericControl lbBranchname = e.Item.FindControl("lbBranchname") as HtmlGenericControl;
BranchName = lbBranchname.InnerText;

ajax CollapsiblePanelExtender inside datalist

I am creating a data list that will have multiple person records displayed inside a collapsible panel and iside each dataItem user can edit the record etc.
Following is my code
<%# Register TagName="CreateEditPerson" Src="~/ascx/create_edit_person.ascx" TagPrefix="WD" %>
<asp:DataList ID="dlPerson" runat="server" OnItemDataBound="dlPerson_OnItemDataBound">
<ItemTemplate>
<div class="personRow">
<div class="personRowHeader" id="divEditPerson">
<div class="lastNameColumn">
<asp:Label ID="lblLastName" runat="server"></asp:Label </div>
<div class="firstNameColumn">
<asp:Label ID="lblFirstName" runat="server"></asp:Label>
</div>
<div class="editColumn">
<asp:Image ID="imgExpandImage" runat="server" Class="divSearchLabel" meta:resourcekey="imgExpandImage" />
<asp:Label ID="lblEditPerson" runat="server" meta:resourcekey="lblEditPerson"></asp:Label>
</div>
<div style="clear: both">
</div>
</div>
<ajaxToolkit:CollapsiblePanelExtender ID="cpPerson" runat="server" meta:resourcekey="cpPerson"
Collapsed="true" TargetControlID="pnlpersonEdit" CollapseControlID="divEditPerson"
ExpandControlID="divEditPerson" TextLabelID="lblEditPerson" CollapsedSize="0"
ScrollContents="false" SuppressPostBack="True" ImageControlID="imgExpandImage">
</ajaxToolkit:CollapsiblePanelExtender>
<asp:Panel ID="pnlpersonEdit" runat="server">
<div class="product_technical_details">
<WD:CreateEditPerson ID="createEditPerson1" runat="server" />
</div>
</asp:Panel>
</div>
</ItemTemplate>
</asp:DataList>
My Problem is,
1. When I click on 1st dataitem panel, All the panels expands. Do i need the dynamic id of the TargetControlID ?
I solved it as follows:
on ItemDataBound event of the datalist, I just set dynamic ID of the collapsible panel, target panel and collaped/expand control; and set the "TargetControlID", "CollapseControlId" and "ExpandControlId"
I am giving the code snippet here:
protected void dlPerson_OnItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
//Find the controls in the Item Template
Panel pnlPersonEdit = e.Item.FindControlRecursive("pnlPersonEdit") as Panel;
CollapsiblePanelExtender cpPersonEdit =
e.Item.FindControlRecursive("cpPersonEdit") as CollapsiblePanelExtender;
//This panel was a div previously "divEditPerson" I have changed it to panel
Panel pnlEditPersonHead = e.Item.FindControlRecursive("pnlEditPersonHead") as Panel;
//Some object from db
PersonObject personObject = e.Item.DataItem as PersonObject;
//Set Id of the collapsed/expanded panel from unique key
pnlEditPersonHead.ID += personObject.CrmddressId.ToString();
//Set Id of the target panel from unique key
pnlPersonEdit.ID += personObject.CrmddressId.ToString();
//simillarly set Id of the collapsible panel extender
cpPersonEdit.ID += personObject.CrmddressId.ToString();
//Now set the TargetControlID, CollapseControlID and ExpandControlID
cpPersonEdit.TargetControlID = pnlPersonEdit.ID;
cpPersonEdit.CollapseControlID = pnlEditPersonHead.ID;
cpPersonEdit.ExpandControlID = pnlEditPersonHead.ID;
}
}

Raise DataGrid ItemCommand event from Javascript

I am using a DataGrid to display data retrieved from a database and I was wondering if it is possible to raise the grid's ItemCommand event using Javascript.
The snippet below shows roughly what I am trying to do within onclick handler for the DIV removeProductButton. I don't want to use asp:Button or asp:LinkButton as currently the look and feel of the DIV is controlled using CSS and the code should work regardless of the type HTML element used to create the click-able trigger to allow for future look and feel customisations.
<asp:datagrid id="itemGrid" runat="server" cellPadding="0" AutoGenerateColumns="False" GridLines="None">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<div class="items">
<div class="product_title"><%#Eval("ItemID")%>. <%#Eval("ItemDescription")%></div>
<div class="product_image">
<img id="productImage_<%#Eval("ItemID")%>" src="<%#Eval("ThumbnailURL")%>" />
</div>
<div class="buttons">
<div id="removeProductButton" class="buttonStandard" onclick="Do Something HERE...">Remove</div>
</div>
</div>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:datagrid>
I have tried using the following code in the grid's ItemCreated event but was not able to get it working
private void itemGrid_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
dynamic itemData = e.Item.DataItem;
HtmlGenericControl removeProductButton = (HtmlGenericControl)e.Item.FindControl("removeProductButton");
removeProductButton.Attributes.Add("onclick", ClientScript.GetPostBackEventReference(removeProductButton, ""));
}
}
Any help would be greatly appreciated.
Add a hidden button to the ItemTemplate with your desired CommandName:
<asp:Button
ID="removeProductButton_hidden"
runat="server"
style="display:none;"
CommandName="YourCommandName"
Text="" />
Make sure that your 'Remove' div has the runat="server" attribute:
<div ID="removeProductButton" runat="server" class="buttonStandard">Remove</div>
Get rid of the grid ItemCreated handler and create a grid ItemDataBound handler that looks like this:
public void grd_ItemDataBound(object sender, DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
HtmlGenericControl removeProductButton = (HtmlGenericControl)e.Item.FindControl("removeProductButton");
Button removeProductButtonHidden = (Button)e.Item.FindControl("removeProductButton_hidden");
removeProductButton.Attributes.Add("onclick", ClientScript.GetPostBackEventReference(removeProductButtonHidden, ""));
}
}
So the entire grid definition would look like this:
<asp:DataGrid
runat="server"
ID="itemGrid"
OnItemCommand="itemGrid_ItemCommand"
OnItemDataBound="itemGrid_ItemDataBound">
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<asp:Button
ID="removeProductButton_hidden"
runat="server"
style="display:none;"
CommandName="YourCommandName"
Text="" />
<div class="items">
<div class="buttons">
<div ID="removeProductButton" runat="server" class="buttonStandard">Remove</div>
</div>
</div>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>

Repeater in ASP.net

I used repeater in asp.net. My problem is don't know how to hide a fields in repeater. There is a regular price and now price if regular price is equal to zero it will hide the fields and if not it will show the value of the regular price. i hope you can help on this.
here my code in asp:
<a href="<%=Utility.GetSiteRoot() %>/BookInfo.aspx?SKU=<%# Utility.SKUMask(Eval("lb_sku").ToString()) %>">
<img width="150px" src='<%# Eval("lb_picturepath")%>'>
</td>
<td valign="top">
<asp:Label ID="lb_titleLabel" runat="server" CssClass="center-head" Text='<%# Eval("lb_title") %>' />
<p><asp:Label ID="lb_descriptionLabel" runat="server" Text='<%# Eval("lb_description") %>' /></p>
<div class="price"><%# "Price: " + decimal.Round((decimal)Eval("lb_sellingprice"),2)%></div>
</td>
</tr>
<tr>
<td></td>
<td>
<a class="addtocart" href="<%=Utility.GetSiteRoot() %>/AddToCart.aspx?SKU=<%# Utility.SKUMask(Eval("lb_sku").ToString()) %>" >Add To Cart</a>
<a href="<%=Utility.GetSiteRoot() %>/BookInfo.aspx?SKU=<%# Utility.SKUMask(Eval("lb_sku").ToString()) %>" class="readmore">
View Details
</a></td>
thanks!
You would need to handle the OnItemDataBound event, and then change the visibility of the control. An example of this is shown below:
ASPX Page
<asp:Repeater ID="MyRepeater" OnItemDataBound="MyRepeater_OnItemDataBound" runat="server">
<ItemTemplate>
<asp:Label ID="RegularPriceLabel" runat="server" />
<br/>
<asp:Label ID="BuyNowPriceLabel" runat="server" />
</ItemTemplate>
</asp:Repeater>
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
MyRepeater.DataSource = GetDataSource();
MyRepeater.DataBind();
}
}
protected void MyRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// This will be your data object
MyEntity o = (MyEntity) e.Item.DataItem;
// Get the labels
Label RegularPriceLabel = (Label) e.Item.FindControl("RegularPriceLabel");
Label BuyNowPriceLabel = (Label) e.Item.FindControl("BuyNowPriceLabel");
// Only show regular price if it is set
RegularPriceLabel.Visible = (o.RegularPrice > 0);
// Populate labels
RegularPriceLabel.Text = o.RegularPrice.ToString();
BuyNowPriceLabel.Text = o.BuyNowPrice.ToString();
}
}
I would take a look at the ItemDataBound event of the Repeater. It will fire for every item in the repeater and allow you to do any code-behind (like hiding labels) more easily.
Edit: For your specific example, since you are formatting the price as well, it may be easier to just call a custom method to to render the price, like so:
ASPX:
<%#RenderPrice((decimal)Eval("lb_sellingprice"))%>
Method:
protected string RenderPrice(decimal price) {
if (price > 0) {
return "Price: $" + decimal.Round(price);
} else {
return string.Empty;
}
}
It's quick-and-dirty but it works.

Categories

Resources