Nested repeater with button - asp.net

in my page I have two nested repeaters as follows:
<asp:Repeater runat="server" ID="rptStanze" OnItemDataBound="rptStanze_ItemDataBound">
<ItemTemplate>
<div>
<li class="datatable-item">
<asp:LinkButton runat="server" ID="hypGetDetails" Text="Get Details" OnCommand="GetObjectDetails" />
<div class="col2">DATE</div>
<div class="col3">VISITORS</div>
</li>
<li>
<asp:Repeater runat="server" ID="rptDetails" OnItemDataBound="rptDetails_ItemDataBound">
<ItemTemplate>
<div class="subitem">
<div class="col2"><asp:Literal runat="server" ID="ltlDetTitle" /></div>
<div class="col3"><asp:Literal runat="server" ID="ltlDetViews" /></div>
<div class="col4"><asp:Literal runat="server" ID="ltlDetComments" /></div>
</div>
</ItemTemplate>
</asp:Repeater>
</li>
</div>
</ItemTemplate>
</asp:Repeater>
In the first, I have a LinkButton with a method that fills the nested repeater. Concerning the bounding of data I've no problems, but I dunno how to get the correct nested repeater to fill. In the GetObjectDetails method how can I get it?

In your Command handler, one of the parameters is the button that sent the request, commonly referred to as the "sender". Using that, you just need to find the container of the button that was clicked and then find the repeater within that container.
Here is a C# example:
protected void GetObjectDetails(object sender, CommandEventArgs e)
{
LinkButton hypGetDetails = (LinkButton)sender;
RepeaterItem ri = (RepeaterItem)hypGetDetails.NamingContainer;
Repeater rptDetails = (Repeater)ri.FindControl("rptDetails");
}

Related

Connecting Session from a repeater's item to another page doesn't work

I want to take the text in the text box from the particular item in the repeater that was clicked, and use it on the page ViewRecipe2.aspx.
Currently, when you click a button on one of the items, it returns back to the repeater's page, but the repeater does not appear, instead of moving to the page ViewRecipe2.aspx.
This is my repeater in aspx:
<asp:Repeater ID="RepeaterR" runat="server">
<ItemTemplate>
<div class="wrapper">
<table>
<div class="box">
<div class="property-card">
<div class="property-image">
<div class="property-image-title">
</div>
</div>
<div class="property-description">
<asp:Button CssClass="h5" runat="server" ID="Button1" OnClick="Button1_Click" Text=<%# Eval("recipeName")%> BackColor="Transparent" BorderColor="Transparent"/>
<p><%#Eval("avgRating") %> stars</p>
<asp:Image class="img" runat="server" src=<%#Eval("recipePic") %> />
<asp:TextBox ID="hiddenTB" runat="server" Text=<%# Eval("recipeName")%> Visible="false"></asp:TextBox>
</div>
</div>
</div>
</table>
</div>
</ItemTemplate>
</asp:Repeater>
This is the code behind on c#:
protected void Button1_Click(object sender, EventArgs e)
{
RepeaterItem item = (sender as Button).NamingContainer as RepeaterItem;
string VR = (item.FindControl("hiddenTB") as TextBox).Text;
if (VR!=null)
{
Session["selectedRecipe"] = VR;
Response.Redirect("ViewRecipe2.aspx");
}
}
This is ViewRecipe2.aspx:
<asp:TextBox ID="TextBoxP" runat="server"></asp:TextBox>
And the code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string theRecipeName = (Session["selectedRecipe"]).ToString();
TextBoxP.Text = theRecipeName;
}
}
Well, text box or hidden field is "never" null.
but, you need quotes around that "text" setting of the hidden field.
<asp:TextBox ID="hiddenTB" runat="server"
Text='<%# Eval("recipeName")%>' Visible="false">
</asp:TextBox>
Also, keep in mind, that with visible=false, then the markup is NOT sent nor rendered client side. This means that client side js code can't use that text box, but server side code can just fine grab the textbox, and then the value as you have.
However, while you "should" have those single quotes?
it should still have worked.
I would for testing, remove the Visible="false", and then you can actually see + verify that the value is correct.

How to get the CommandArgument of an ImageButton inside a Repeater

I have a repeater which structured like this
<asp:Repeater ID="RpAccBind" runat="server" OnItemDataBound="RpAccBind_ItemDataBound">
<ItemTemplate>
<tr id="acsryRow" runat="server">
<td data-th="Product">
<div class="prodImgMain">
<img src="../instrumentimages/<%# Eval("ProductImage") %>" alt="<%# Eval("ProductName")%>" />
</div>
</td>
<td data-th="Description">
<div class="prodDescriptionContainer">
<ul>
<li>
<span class="prdRow"><%# Eval("ProductName") %></span>
</li>
</ul>
</div>
<div class="quantityIconWrap form-group">
<span class="number-wrapper">
<asp:TextBox Text='<%# Eval("Quantity") %>' ID="txtqty" CssClass="form-control" runat="server" size="3" Width="50" onkeyup="this.value=this.value.replace(/[^0-9]/g,'');" OnTextChanged="txtQtyTextChanged" AutoPostBack="true"></asp:TextBox>
</span>
<span>
<asp:ImageButton ID="lnkAscRemove" runat="server" class="btn" OnClick="lnkRemoveClick" CommandArgument='<%# Eval("ProductId")%>' ImageUrl="../images/deleteIcon.png"></asp:ImageButton>
</span>
</div>
</td>
<td data-th="Amount" style="padding-right: 5%;">
<div class="amountColMain">
<ul>
<li><span><strong><span id="litConPrice" runat="server">$<%# Eval("ConsumerPrice") %></span></strong></span></li>
</ul>
</div>
</td>
<td></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
Now, whenever the txtQty is 0, i want to have the productid in respect of the imagebutton clicked. Right Now, i am using something like
long productId = Convert.ToInt64(((ImageButton)((RepeaterItem)txtQty.Parent).FindControl("lnkAscRemove")).CommandArgument);
It is giving me an error of unable to cast HtmlTableCell to RepeaterItem
Any Kind of help will be appreciated. Thanks in advance
To use CommandName and CommandArgument, you need to use a Command event, not a Click.
<asp:ImageButton ID="lnkAscRemove" runat="server" OnCommand="lnkAscRemove_Command"
CommandArgument='<%# Eval("ProductId")%>'
Code behind
protected void lnkAscRemove_Command(object sender, CommandEventArgs e)
{
Label1.Text = e.CommandArgument.ToString();
}
Update
If you want to get the ProductId from a TextBox, you could add it as a custom property and then read it in code behind.
<asp:TextBox Text='<%# Eval("ProductId") %>' ID="txtqty" runat="server" AutoPostBack="true"
OnTextChanged="txtqty_TextChanged" ProductId='<%# Eval("ProductId") %>'></asp:TextBox>
Code behind
protected void txtqty_TextChanged(object sender, EventArgs e)
{
TextBox tb = sender as TextBox;
Label1.Text = tb.Attributes["ProductId"];
}
The Repeater has an ItemCommand that watches for button events inside the Repeater elements. The CommandName and CommandArgument is passed to the event.
Also of importance is the Item which represents the Repeater Item that the button was clicked in. Then you can use the FindControls method to find related server controls object for the same RepeaterItem in which the button was clicked.
protected void MyRepeater_ItemCommand(Object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "edit") {
SetEditorTo(e.CommandArgument);
}
RepeaterItem row = e.Item;
Textbox tQty = row.FindControls("txtqty");
}

Saving a comment from inside an updatepanel in a repeater

(Asp.net 4)
I have a blog where i use a repeater to show all the blog-articles and the comments to each blog. I'm trying to change how the users can post comments to the blog. I want to put the comments under each blog in an UpdatePanel, and when they write a comment and click on a save-button, i want to refresh the comments, so their new comment will show. But I'm having difficulties achieving this.
I've added the UpdatePanel in the ItemTemplate of the Repeater, and added the Textboxes and Button for saving the comment. Each UpdatePanel is placed in a with the id of the blog. But I don't know how to create the code for saving the comment for the correct blog-id, and then to refresh that UpdatePanel.
Code:
<asp:Repeater ID="RepeaterBlog" runat="server">
<ItemTemplate>
<article>
<% if (repeaterCounter == 0)
{
Response.Write("<header class=\"firstArticleInBlog\">");
}
else
{
Response.Write("<header class=\"normalArticle\">");
}
%>
<h2><%# Eval("article_header") %> <span class="date">
<time datetime="<%# GetPubDate(Eval("article_date")) %>"><%# FormatDate(Eval("article_date")) %></time></span></h2></header>
<p><%# Eval("article_content") %><p><br />
<div class="comments">
<div class="showhidecomments">
<!--<a class="iframe-comments" data-fancybox-type="iframe" href='WriteComments.aspx?BlogId=<%# DataBinder.Eval(Container, "DataItem.id") %>'>Skriv kommentar</a> | -->
Vis/Skriv kommentarer (<%# CountComments (DataBinder.Eval(Container, "DataItem.id")) %>) | <a href="javascript:void(0);" title="i<%# Eval("id") %>" >Skjul kommentarer</a>
</div>
<section>
<article>
<div id="i<%# Eval("id") %>" style="display: none;">
<asp:UpdatePanel ID="upPanel" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="cmdSaveComment" EventName="Click" />
</Triggers>
<ContentTemplate>
<%# GetComments (DataBinder.Eval(Container, "DataItem.id")) %>
<asp:TextBox ID="txtName" runat="server" />
<asp:TextBox ID="txtComment" runat="server" TextMode="MultiLine" />
<asp:Button ID="cmdSaveComment" runat="server" OnClick="cmdSaveComment_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</article>
</section>
</div>
<% repeaterCounter++; %>
</article>
</ItemTemplate>
</asp:Repeater>
And in the code-behind:
protected void cmdSaveComment_Click(object sender, EventArgs e)
{
//simplified code:
string name = txtName.Text;
string comment = txtComment.Text;
int blogId = (int)(Eval("DataItem.id"));
dataHandler.NewComment(name, comment, blogId);
}
Am i at least close to something here, or am i completely on the wrong track?
You need to use the ItemCommand property for the repeater and the CommandName property for your button.
First declare the event name for the repeater and the button's command name in your aspx. Note the CommandName replaces the OnClick for your button. Also you give the button a command argument, this being the ID for the article record that the comment is for.
<asp:Repeater ID="RepeaterBlog" runat="server" OnItemCommand="RepeaterBlog_ItemCommand">
<asp:Button ID="cmdSaveComment" runat="server" CommandName="SaveComment" CommandArgument='<%# Eval("id")%>' />
Now add this in the code behind
void RepeaterBlog_ItemCommand(Object Sender, RepeaterCommandEventArgs e) {
if(e.CommandName == "SaveComment") {
string name = ((TextBox)e.Item.FindControl("txtName")).Text;
string comment = ((TextBox)e.Item.FindControl("txtComment")).Text;
dataHandler.NewComment(name, comment, e.CommandArgument);
}
}
That should get you started

How to loop in repeater dataitems after page post back

I have a button in repeater and I want to loop in data items of repeater in this button click event. Here is my code:
protected void btnPromotionButton_OnClick(object sender, EventArgs e)
{
try
{
foreach (RepeaterItem item in rptPromotionProducts.Items)
{
if (item.DataItem == null)
{
continue;
}...
And here is my repeater:
<asp:Repeater ID="rptPromotionProducts" runat="server" OnItemDataBound="rptPromotionProducts_OnItemDataBound">
<ItemTemplate>
<li>
<asp:HyperLink runat="server" ID="hlProduct" CssClass="product_image">
<asp:Image runat="server" ID="imgWindow" />
</asp:HyperLink>
<div class="product_info">
<h3>
<a href="#">
<%# Eval("Name") %></a></h3>
</div>
<div>
<asp:Button ID="btnPromotionButton" runat="server" Text="Sepete Ekle" OnClick="btnPromotionButton_OnClick" />
</div>
</div>
</li>
</ItemTemplate>
</asp:Repeater>
item.DataItem is always comes null however repeater has rows. Is that possible to loop after page post and back?
Similar questions was already answered here and here.
The short answer for this question is NO. You cannot access the DataItem after postback.
Alternatives to retrieve your data would be use a Hidden Field, a DataSource linked to your Repeater or a session object containing the data.

Shading every other row in a VB.net Listview?

I have been Googling this for about a day now, and every post I find is too old and Visual Studio doesn't recognize some pieces of code that people have posted. I have a dynamically populated Listview. I would really like every other line to be shaded for readability purposes, and just can't figure it out.
Everything I try to do messes with the Modal PopupExtender that I have inside of the Listview. It trys to shade the lines inside the PopUpBox too. This is one of the Listviews that I would like shaded.
<!-- Descriptions -->
<asp:TabPanel ID="tab2" runat="server" HeaderText="Descriptions">
<HeaderTemplate>Descriptions</HeaderTemplate>
<ContentTemplate>
<ul class="info">
<asp:ListView ID="lvDescriptions" runat="server" DataSourceID="dsMarketingDescriptions" DataKeyNames="MarketingID">
<ItemTemplate>
<li>
<asp:LinkButton ID="ViewDescriptionButton" runat="server"><%#Eval("MarketingTitle")%></asp:LinkButton>
<asp:Panel ID="ViewDescriptionPanel" runat="server" CssClass="DescModalPopup"> <div class="PopupHeader" id="PopupHeader">View Description
<asp:ImageButton ID="CancelDescriptionButton" runat="server" ImageUrl="../../images/exit.png" AlternateText="" Style="float:right;"/>
</div>
<asp:Label ID="Description" runat="server" style="padding:5px;"><%# Eval("MarketingData") %></asp:Label>
</asp:Panel>
<asp:ModalPopupExtender ID="ViewDescriptionModal" runat="server" BackgroundCssClass="modalBackground" DropShadow="false" DynamicServicePath="" Enabled="true" PopupControlID="ViewDescriptionPanel" TargetControlID="ViewDescriptionButton" CancelControlID="CancelDescriptionButton"></asp:ModalPopupExtender>
</li>
</ItemTemplate>
</asp:ListView>
</ul>
</ContentTemplate>
</asp:TabPanel>
Try using the AlternatingItemTemplate to specify a different background color for alternating items.
Are you trying to do something like this with the ModalPopupExtender?:
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
Panel pnl = e.Item.FindControl("Panel1") as Panel;
if (pnl != null)
{
pnl.BackColor = ListView1.Items.IndexOf(e.Item) % 2 == 1 ? Color.PeachPuff : Color.White;
}
}

Resources