how to understand which rows selected in repeater? - asp.net

I have a slideshow that images load from sql server.
here is my html code:
<!-- Elastislide Carousel -->
<ul id="Ul1" class="elastislide-list">
<asp:Repeater ID="Repeater2" runat="server">
<ItemTemplate>
<li>
<asp:Label ID="lbl" runat="server" Text='<%#Eval("IDMusic") %>' Visible="True"></asp:Label>
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl='<%#Eval("ImageUrl") %>' Width="250px" Height="250px" OnClick="ImageButton1_Click" />
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
<!-- End Elastislide Carousel -->
<br /><br />
</div>
</div>
Now when, I run Project and user click on one of the imageButtons, I want to understand what is he/she clicked? for example he/she click on second ImageButton, Then I want to save IDMusic into a session and use this session in another page but I don't know how can i get IDmusic user clicked on?
here is my code behind :
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
foreach (RepeaterItem item in Repeater2.Items)
{
Label lbl = (Label)item.FindControl("lbl");
if (lbl != null)
{
Session["selectedmusicID"] = lbl.Text;
}
}
Response.Redirect("music.aspx");
}

There is no easy way to do so while handling click on the image itself. However you can leverage ItemCommand event here, which is a repeater event. Basically when some control is clicked inside the repeater, it generates a command in repeater which you can handle, and you can have item-specific arguments for it.
To define a command and args:
<asp:ImageButton ID="ImageButton1" ... CommandName="Select" CommandArgument='<%#Eval("IDMusic") %>' />
Command name here is custom, choose whatever you like. Now subscribe to the event of the repeater:
<asp:Repeater ID="Repeater2" runat="server"
OnItemCommand="Repeater2_ItemCommand">
And to handle:
protected void Repeater2_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Select") //just in case you have more than one
{
e.CommandArgument //here is your ID
}
}

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.

asp.net ajax like reorder list

I'm trying to create a draggable list to change the order some pictures are displayed in a product page. I wan't to be able to do this in the product edit page (same place where I add the pics and their description). So, when creating I have nothing inserted on the database and since the AJAX toolkit reorderlist only works with a datasource I was specifying the list as the source of the reorderlist and calling the databind method. In the item template of the reorder list I have a textbox to edit the pic description and a img that displays the photo. I can drag the items and the list gets reordered, however when I click save I can't get the updated text on the textbox and the order property on the picture doesn't get updated. I've tried manually getting the items in the reorderlist but they're always null even though the list shows 20 items the DataItem is empty. I've enabled viewstate and didn't help either.
Here's my code:
<ajaxToolkit:ReorderList ID="rdlPhotos" runat="server" SortOrderField="PhotoOrder" AllowReorder="true" PostBackOnReorder="true" ClientIDMode="AutoID" EnableViewState="true" ViewStateMode="Enabled">
<ItemTemplate>
<div>
<%--<eva:PhotoView ID="iPV" runat="server" Photo='<%# Container.DataItem %>' />--%>
<asp:Image ID="imgPhoto" runat="server" ImageUrl='<%# string.Format("http://eva-atelier.net/sparkle{0}", Eval("Path").ToString().Substring(1)) %>' Width="150" Height="150" />
<div class="formGrid">
<label class="formLabel">Title</label>
<asp:TextBox ID="txtTitle" runat="server" Text='<%#Bind("FileTitle") %>' />
<br />
<label class="formLabel">Description</label>
<asp:TextBox ID="txtDescription" runat="server" Text='<%#Bind("FileDescription") %>' />
<br />
</div>
<p>
<asp:Button ID="btnRemove" runat="server" Text="Remover" />
</p>
</div>
</ItemTemplate>
<ReorderTemplate>
<asp:Panel ID="pnlReorder" runat="server" />
</ReorderTemplate>
<DragHandleTemplate>
<div style="width:20px;height:20px;background-color:Red"></div>
</DragHandleTemplate>
</ajaxToolkit:ReorderList>
And below the C# code:
private void AddPhotosView()
{
if (_currentProduct.Photos != null && _currentProduct.Photos.Count > 0)
{
rdlPhotos.DataSource = _currentProduct.Photos;
rdlPhotos.DataBind();
}
}
I'm new to Asp.net I come from a large WPF background, sorry if I'm making basic question :)
Thanks
For updating order of ReorderList items add your handler for it's OnItemReorder event. In this case your handler may looks like this:
protected void ReorderHandler(object sender, ReorderListItemReorderEventArgs e)
{
var movedPhoto = _currentProduct.Photos[e.OldIndex];
_currentProduct.Photos.RemoveAt(e.OldIndex);
_currentProduct.Photos.Insert(e.NewIndex, movedPhoto);
_currentProduct.Photos.Save();
}
For updating FileTitle and FileDescription of single Photo it is easy to use OnUpdateCommand event of ReorderList and a button with attribute CommandName="Update" for each Photo.
And for updating all Photos at once just iterate through rdlPhotos.Items in next manner:
protected void SaveAllHandler(object sender, EventArgs e)
{
foreach (var riItem in rdlPhotos.Items)
{
var id = ((HiddenField)riItem.FindControl("itemID")).Value;
var title = ((TextBox)riItem.FindControl("txtTitle")).Text;
var description = ((TextBox)riItem.FindControl("txtDescription")).Text;
UpdatePhoto(id, title, description);
}
}
Remember that rdlPhotos.Items here are in initial order. And for identifying which Photo should be updated add hidden field with Photo.ID-value to ReorderList's ItemTemplate like this:
<asp:HiddenField runat="server" ID="itemID" Value='<%# Eval("ID") %>' />

How to prevent page being postbacked when i transfer item from one listbox to other

I have two listboxes in my application on button click i am pushing the item from one list box to other , the code works fine but it causes postback , while i move the item from one list box to other whole page is being loaded again , how i can prevent this .
This will be the code on my aspx page
<div class="bx1">
<telerik:RadListBox ID="RadListBox1" runat="server" DataTextField="Name" DataValueField="Id"
Width="250px">
</telerik:RadListBox>
</div>
<div style="height:7px"></div>
<div class="bx5">
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="images/dwnArrow.png" OnClick="MoveDownClick" />
<asp:ImageButton ID="ImageButton2" runat="server" ImageUrl="images/uparrow.png" OnClick="MoveUpClick" />
</div>
<div style="height:7px"></div>
<div class="bx1">
<telerik:RadListBox ID="RadListBox2" runat="server" DataTextField="Name"
DataValueField="Id" Width="250px" >
</telerik:RadListBox>
</div>
This is my code behind for listbox
protected void MoveDownClick(object sender, EventArgs e)
{
if (RadListBox1.SelectedIndex < 0)
{
}
else
{
RadListBox2.Items.Add(RadListBox1.SelectedItem);
RadListBox1.Items.Remove(RadListBox1.SelectedItem);
RadListBox2.SelectedItem.Selected = false;
}
}
protected void MoveUpClick(object sender, EventArgs e)
{
if (RadListBox2.SelectedIndex < 0)
{
}
else
{
RadListBox1.Items.Add(RadListBox2.SelectedItem);
RadListBox2.Items.Remove(RadListBox2.SelectedItem);
RadListBox1.SelectedItem.Selected = false;
}
}
If your version of Visual Studio is less than 2008, then first download the ajax from the following site and install it:
http://ajaxcontroltoolkit.codeplex.com/
Add a reference to the System.Web.Extensions dll and then add the following line right after your opening <form> tag:
<asp:ScriptManager runat="server" ID="Script1"></asp:ScriptManager>
Replace the Your Code in following piece of code with your entire code that you have written above:
<asp:UpdatePanel runat="Server" ID="u1">
<ContentTemplate>
Your Code
</ContentTemplate>
</asp:UpdatePanel>
That's it, this will stop posting back your page.
Take the time to look into using jQuery along with Microsoft's Ajax with Update Panels or moving into jQuery exclusively where possible. Here are two links that are excellent reads regarding the subject:
Microsoft Ajax? http://encosia.com/why-aspnet-ajax-updatepanels-are-dangerous/
jQuery Ajax: http://net.tutsplus.com/tutorials/javascript-ajax/5-ways-to-make-ajax-calls-with-jquery/

How do I maintain user entered text in a TextBox nested in an UpdatePanel between updates?

I have an ASP.Net UpdatePanel that updates on a timer. Within the UpdatePanel and nested in a GridView, I have a TextBox that the user enters a value in with a submit button. Everything works fine, except if the user does not submit the value before the timed interval, the text is removed from the TextBox.
Is there a way to persist the user entry into the TextBox between updates? Is there a better way of doing this?
All suggestions welcome.
Respectfully,
Ray K. Ragan
Code Postscript:
aspx:
<script type="text/javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(beginRequest);
function beginRequest() {
prm._scrollPosition = null;
}
</script>
<asp:Timer ID="Timer1" runat="server" Interval="900" OnTick="Timer1_Tick"></asp:Timer>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:DataList RepeatColumns="5" RepeatDirection="Horizontal" ID="dlMine" runat="server" OnItemCommand="Item_Command">
<ItemTemplate>
<div style="border:1px solid black;margin:3px;height:300px;text-align:center;padding:5px;">
<div style="width:150px;">
<asp:Label ID="lblTitle" runat="server" Text='<%# left(DataBinder.Eval(Container.DataItem,"title").ToString(), 75) %>'></asp:Label>
</div>
<asp:Label ID="Label1" runat="server" Text='<%# (DateTime)DataBinder.Eval(Container.DataItem,"end_date") %>'></asp:Label>
<br />
<asp:Label ID="Label2" runat="server" Text='<%# String.Format("{0:C}",DataBinder.Eval(Container.DataItem,"current_value")) %>'></asp:Label>
<br />
<asp:TextBox ID="txtNewValue" runat="server"></asp:TextBox>
<asp:Button Visible='<%# (isInThePast((DateTime)DataBinder.Eval(Container.DataItem,"end_date"))) ? false : true %>' CssClass="bid_button" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Revalue" ID="btnBid" Text="Submit New Valuation" />
</div>
</ItemTemplate>
</asp:DataList>
</ContentTemplate>
</asp:UpdatePanel>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
Timer1.Tick += new EventHandler<EventArgs>(Timer1_Tick);
if (!IsPostBack)
{
dataBindList();
}
}
protected void dataBindList()
{
if (Request.QueryString["GroupID"] != null)//Are they coming here with a URL var? If so, build content object
{
List<Item> itemList = ItemManager.getItemsByGroupID(Request.QueryString["GroupID"].ToString());
dlMine.DataSource = itemList.Take(15);
dlMine.DataBind();
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
dataBindList();
UpdatePanel1.Update();
}
protected void Item_Command(Object sender, DataListCommandEventArgs e)
{
if (e.CommandName == "Revalue")
{
Person p = (Person)Session["Person"];
foreach (DataListItem item in dlMine.Items)
{
string textBoxText = ((TextBox)item.FindControl("txtNewValue")).Text;
Utilities.writeLog("txtNewValue: " + textBoxText, 1);
}
dataBindList();
UpdatePanel1.Update();
}
}
You're rebinding the DataList every time the Timer ticks. All changes in the ItemTemplates of the DataList will be lost on postback.
Why not use Javascript to "pause" the timer whenver one of the textboxes gains focus. This will prevent the Timer from firing and let users finish entering text. Once they leave the textbox of "onblur" then you can restart the timer.
Update
The following will take a bit of effort to make it happen but you can do something like:
When the Timer posts back, before rebinding, iterate over the DataList while searching for textboxes with text in them. Something like:
foreach (DataListItem item in dlMine.Items)
{
//find the textbox control and check for text
}
At this point, you'll know which rows need there textboxes repopulated. Store this information in a hashtable.
In the DataList ItemDataBound event, check each rowID against the hashtable to see if its corresponding textbox exists. If so, repopulate the textbox in the DataList row.
Are you initializing the TextBbox value in your code-behind, perhaps in Page_Load or another page method?
TextBox1.Text = "";
If so, that code is executing on every timer event. You can prevent that like this:
if (! IsPostback) {
TextBox1.Text = "";
}
The first request that hits an ASP.NET page is usually an HTTP GET request, while ASP.NET buttons and update panel events issue HTTP POST requests. So the code above will clear TextBox1 the first time you access the page, but leave the value alone when receiving requests from itself. (If you really are setting the text box's value to its default - empty - you could just remove the initialization code.)

Dynamicly created repeater and ItemCommand event problem

A strange problem.
On my page i have a placeholder where I create a repeater on run time.
In ItemTemplate i have a button that invokes repeater_ItemCommand event.
I put a breakpoint on first line of repeater_ItemCommand event, when the button is triggered the event is invoked as planned, but after RebindRepeaters() is finished, when i click on the button again repeater_ItemCommand event is not invoked!
Only if i click on the button one again it invokes, in other scenarios(this is simple version of my page, in original page i have updatepanel that complex everything) it never invokes!
My aspx code:
<form id="form1" runat="server">
<div id="talk">
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</div>
My Code-behind:
protected void Page_Init(object sender, EventArgs e)
{
RebindRepeaters();
}
void RebindRepeaters()
{
PlaceHolder1.Controls.Clear();
CreateRepeater(PlaceHolder1);
}
void CreateRepeater(Control container)
{
Repeater repeater1 = new Repeater();
repeater1.ItemCommand += new RepeaterCommandEventHandler(repeater_ItemCommand);
repeater1.ItemTemplate = Page.LoadTemplate("CommentsTemplate.ascx");
container.Controls.Add(repeater1);
repeater1.DataSource = Comment.GetCommentsP(8, 0);
repeater1.DataBind();
}
void repeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
switch (e.CommandName)
{
case "Edit":
RebindRepeaters();
break;
}
}
The CommentsTemplate.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="CommentsTemplate.ascx.cs" Inherits="CommentsTemplate" %>
<ul>
<li>
<div class="show">
<div class="c">
<asp:LinkButton ID="lbtnTitle" runat="server" Text='<%#Eval("EncodedTitle")%>'
CausesValidation="false" CommandName="VoteUp" OnClientClick="viewHide(this);return false;" CommandArgument='<%#Eval("ID")%>'></asp:LinkButton>
<p class="d"><%#Eval("AddedBy")%>,<%#Eval("AddedDate")%></p>
<div class="CommentBody"><%# Eval("EncodedBody") %>
</div>
</div>
<div class="userpanel">
<asp:Panel runat="server" ID="panAdmin" Visible='<%# UserCanEdit %>' style="float:left;">
<asp:ImageButton runat="server" ID="btnSelect" CommandName="Edit" CommandArgument='<%# Eval("ID") %>'
CausesValidation="false" AlternateText="Edit comment" ImageUrl="~/Images/Edit.gif" />
<asp:ImageButton runat="server" ID="btnDelete" CommandName="Delete" CommandArgument='<%# Eval("ID") %>'
CausesValidation="false" AlternateText="Delete comment" ImageUrl="~/Images/Delete.gif"
OnClientClick="if (confirm('Are you sure you want to delete this comment?') == false) return false;" />
</asp:Panel>
</div>
</div>
</li>
</ul>
If you need more info just ask.
Could you try overidding createChildcontrols and add the RebindRepeaters call there instead of in Page_Init? And make sure to give your repeater an explicit ID:
Repeater repeater1 = new Repeater();
repeater1.ID = "repeater1";
Without an id the asp.net event handling won't know where the event was called from.
Dynamic controls have to be re-added on every postback in order for their events to fire. A new control tree is being created on the postback and the dynamic control is no longer in it, therefore ASP.NET can't evaluate the change in order to fire the event.
EDIT: I was able to fire the event each click by removing RebindRepeaters(). You were binding it twice, once here and once in (Page_Init):
void repeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
switch (e.CommandName)
{
case "Edit":
//RebindRepeaters();
break;
}
}

Resources