OnClick Event for panel which is inside a repeater - c#

<asp:Panel id="contactsListContainer" runat="server">
<asp:Repeater ID="contactsListRepeater" runat="server">
<ItemTemplate>
<asp:Panel CssClass="contactsList" ID="contactList" runat="server" OnClick="contactLink_Click" CommandArgument='<%# ((AddressBook.Employee)Container.DataItem).Id %>' CausesValidation="false">
<asp:Label ID="lblContactName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Name") %>'></asp:Label>
<asp:Label ID="lblContactEmail" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Email") %>'></asp:Label>
<asp:Label ID="lblContactMobile" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "MobileNumber") %>'></asp:Label>
</asp:Panel>
</ItemTemplate>
</asp:Repeater>
</asp:Panel>
I want to add onclick event for contactlist panel. how can i add it.
This is the code what is to be done when that panel is clicked.
protected void contactLink_Click(object sender, EventArgs e)
{
contactsForm.Style.Add("display", "none");
detailsContainer.Style.Add("display", "block");
LinkButton btn = (LinkButton)sender;
SelectEmpId = int.Parse(btn.CommandArgument);
LinkButton contactListLinkButton = getSelctedLinkButton();
contactListLinkButton.Style.Add("background-color", "#CEE7F2");
Employee employee = GetEmployee(SelectEmpId);
lblDetailName.Text = employee.Name;
lblDetailAddress.Text = employee.Address;
lblDetailMobile.Text = employee.MobileNumber;
lblDetailLandline.Text = employee.LandLineNumber;
lblDetailEmail.Text = employee.Email;
lblDetailWebsite.Text = employee.Website;
lblDetailAddress.Text = employee.Address;
}

There is no OnClick event for Asp.NET Panel, try this instead:
You can refer to this solution: https://stackoverflow.com/a/20540854/4779385
Hope it helps!

The <asp:Panel> does not have a Click event you can handle.
Although you will probably have some CSS work to do, a good approach is to wrap the content you want to be server-clickable inside an HTML anchor, i.e.
<a id="anchor" runat="server">
.. your stuff
</a>
You can add a Clicked handler to the anchor inside the repeater/grid's ItemDataBound event, and specify your contactLink_Click handler is the one to handle the event for all anchors/panels in the repeater/grid.
(this example is from a repeater, adapt it for a GridView)
void contactsListRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var item = e.Item;
if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)
{
var anchor = item.FindControl("anchor") as HtmlAnchor;
anchor.ServerClick += contactLink_Click;
}
}
Note that the sender will be the anchor that raises the click event, so you can drill down into the correct child controls from sender (if you need to)

Related

How to make button visible inside repeater?

Here I have kept two button(btnhide and btnunhide) and a label inside the repeater and I have made button btnunhide invisible initially. Now what I want is that as I press button btnhide then btnunhide which is invisible intially should be visible.
Solution Will Be great help.
Html used
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand" >
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="btn" CommandName="h" runat="server" Text="Hide" />
<asp:Button ID="btnhide" Visible="false" runat="server" Text="Unhide" />
</ItemTemplate>
</asp:Repeater>
Code behind
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "h")
{
}
}
You can achieve this by just a single button by changing the Text to hide/unhide and do the functionality as required by just checking the Text property of the button.
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "h")
{
Button btn = (Button)(e.CommandSource);
if(btn.Text == "hide")
{
btn.Text = "unhide";
//Do additional work here, when unhiding.
}
else
{
btn.Text = "hide";
//Do additional work here, when hiding.
}
}
}
I Hope, this helps. Thanks

ItemList FindControl working for 1 item

I have a LinkButton within my ItemTemplate of my ListView:
<asp:ListView ID="lvNotification" runat="server">
<ItemTemplate>
<asp:LinkButton runat="server" ID="lbReject" OnClick="Reject_Click" CommandArgument='<%# Eval("offerID") %>' Text="Reject" />
</ItemTemplate>
</asp:ListView>
Then in my code I have:
protected void Reject_Click(object sender, EventArgs e)
{
var lbreject = lvNotification.Items[0].FindControl("lbReject") as LinkButton;
string c = lbreject.CommandArgument;
}
The ListView retrieves 4 rows correctly, and I have placed the Eval("offerID") and it shows an offerID for each item in the list, however when I place it as the CommandArgument in the LinkButton and debug it, it shows the value 1 on ever item in the ListView, I am trying to place the offerID in each LinkButton CommandArgument and be able to access it, but I cannnot do so.
What am I doing wrong?
That is because you are always checking the first item (0 index). You can get the LinkButton from the sender and check its command argument.
protected void Reject_Click(object sender, EventArgs e)
{
var lbreject = (LinkButton)sender;
string c = lbreject.CommandArgument;
}
Here actually OnItemCommand event of ListView can be handy. This way you can control all events from the single point:
<asp:ListView ID="lvNotification" OnItemCommand="lvNotification_OnItemCommand" runat="server">
<ItemTemplate>
<asp:LinkButton runat="server" ID="lbReject" CommandName="Reject_Click" CommandArgument='<%# Eval("offerID") %>' Text="Reject" />
</ItemTemplate>
</asp:ListView>
protected void lvNotification_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Reject_Click"))//or any other event
{
LinkButton lbreject = (LinkButton) sender;
string c = lbreject.CommandArgument;
}
}

How to access a legend tag from code

I have the following data-bound repeater code :
<%--categories--%>
<asp:Repeater ID="CategoryRepeater" runat="server" OnItemDataBound="ItemBound">
<ItemTemplate>
<div class="groupbox">
<fieldset>
<legend><%# Container.DataItem %></legend>
<table>
<asp:Repeater ID="ItemRepeater" runat="server">
<ItemTemplate>
<tr>
<td>
<asp:CheckBox id="chkItem" runat="server" Text='<%# Eval("Text")%>' />
<asp:HiddenField id="pgNos" runat="server" Value='<%# Eval("PGNos")%>' />
<asp:Button ID="btnXRefs" Text="x-refs" runat="server" CssClass="xRefButton" OnClick="btnSelectXRefs_Click" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
</fieldset>
</div>
</ItemTemplate>
</asp:Repeater>
There is a repeater inside a repeater. How do I access the text inside the legend (<legend><%# Container.DataItem %></legend>) from code?
I tried :
foreach (RepeaterItem cr in CategoryRepeater.Items)
{
string heading = (string) cr.DataItem; // returns null
}
Container.DataItem is a runtime alias for the DataItem for this specific item in the bound list. For a Repeater which displays 10 rows of data, this is one row from the datasource...Basically, it's a specific row and at runtime you can get the Property Values from this row
I saw your above Mark Up...Seems like you are missing to mention the property of Data-Bound type Class like below.
<%# ((Your Class Name)Container.DataItem).Class Property Name %>
There is a repeater inside a repeater. How do I access the text inside
the legend (<%# Container.DataItem %>) from code?
As told by phemt.latd, you can change the Legend tag into server side control like below.
<legend id="lg" runat="server">
<%# ((Your Class Name)Container.DataItem).Class Property Name %>
</legend>
Now, in the Item-Bound Data Event, Find the Legend Control.
protected void rpt_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
HtmlGenericControl ctl = (HtmlGenericControl)e.Item.FindControl("lg");
ctl.InnerText //This is what will give you the result.
}
}
The legend tag that you use is not visible on server side. Is a client control and not a server one.
Try with this:
<legend id="myLegend" runat="server"><%# Container.DataItem %></legend>
Then in codebehind:
protected void ItemBound(Object sender, RepeaterItemEventArgs e)
{
if (e.Item.DataItem == null) return;
HtmlGenerics body = (HtmlGenerics)e.Item.FindControl("myLegend");
body.InnerText = "Foo";
}

ASP.NET Repeater: Button in item template to redirect to another page

I have a repeater and each item contains a button which should redirect to another page and also pass a value in the query string.
I am not getting any errors, but when I click the button, the page just refreshes (so I am assuming a postback does occur) and does not redirect. I think that for some reason, it isn't recognizing the CommandName of the button.
Repeater code:
<asp:Repeater ID="MySponsoredChildrenList" runat="server" OnItemDataBound="MySponsoredChildrenList_ItemDataBound" OnItemCommand="MySponsoredChildrenList_ItemCommand">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<br />
<div id="OuterDiv">
<div id="InnerLeft">
<asp:Image ID="ProfilePic" runat="server" ImageUrl='<%#"~/Resources/Children Images/" + String.Format("{0}", Eval("Primary_Image")) %>'
Width='300px' Style="max-height: 500px" /></div>
<div id="InnerRight">
<asp:HiddenField ID="ChildID" runat="server" Value='<%# DataBinder.Eval(Container.DataItem, "Child_ID") %>'/>
<span style="font-size: 20px; font-weight:bold;"><%# DataBinder.Eval(Container.DataItem, "Name") %>
<%# DataBinder.Eval(Container.DataItem, "Surname") %></span>
<br /><br /><br />
What have you been up to?
<br /><br />
<span style="font-style:italic">"<%# DataBinder.Eval(Container.DataItem, "MostRecentUpdate")%>"</span>
<span style="font-weight:bold"> -<%# DataBinder.Eval(Container.DataItem, "Update_Date", "{0:dd/MM/yyyy}")%></span><br /><br /><br />Sponsored till:
<%# DataBinder.Eval(Container.DataItem, "End_Date", "{0:dd/MM/yyyy}")%>
<br /><br />
<asp:Button ID="ChildProfileButton" runat="server" Text="View Profile" CommandName="ViewProfile" />
</div>
</div>
<br />
</ItemTemplate>
<SeparatorTemplate>
<div id="SeparatorDiv">
</div>
</SeparatorTemplate>
</asp:Repeater>
C# Code behind:
protected void MySponsoredChildrenList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
// Stuff to databind
Button myButton = (Button)e.Item.FindControl("ChildProfileButton");
myButton.CommandName = "ViewProfile"; }
}
protected void MySponsoredChildrenList_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "ViewProfile")
{
int ChildIDQuery = Convert.ToInt32(e.Item.FindControl("ChildID"));
Response.Redirect("~/ChildDescription.aspx?ID=" + ChildIDQuery);
}
}
I am new to using repeaters so it's probably just a rookie mistake. On a side note: is there a better way of obtaining the ChildID without using a hidden field?
EDIT: Using breakpoints; the ItemDatabound event handler is being hit, but the ItemCommand is not being entered at all
You need to set MySponsoredChildrenList_ItemDataBound as protected. Right now, you have just 'void' which by default is private, and is not accessible to the front aspx page.
Another way is to use the add event handler syntax from a function in your code behind, using the += operator.
Either way, the breakpoint will now be hit and our code should mwork.
EDIT: So the above solved the compilation error but the breakpoints are not being hit; I've ran some tests and am able to hit breakpoints like this:
Since I do not know how you are databinding, I just added this code to my code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MySponsoredChildrenList.DataSource = new List<object>() { null };
MySponsoredChildrenList.DataBind();
}
}
Note: If you DataBind() and ItemDataBound() is called on every postback, it will wipe out the command argument, which is potentially what you are seeeing; so if you always see [object]_ItemDataBound() breakpoint hit, but never [object]_ItemCommand(), it is because you need to databind only on the initial page load, or after any major changes are made.
Note also the method MySponsoredChildrenList_ItemCommand doesn't work:
protected void MySponsoredChildrenList_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "ViewProfile")
{
int ChildIDQuery = Convert.ToInt32(e.Item.FindControl("ChildID"));
Response.Redirect("~/ChildDescription.aspx?ID=" + ChildIDQuery);
}
}
When you do FindControl, you need to cast to the correct control type, and also make sure to check for empty and null values before converting, or else you will possibly have errors:
protected void MySponsoredChildrenList_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "ViewProfile")
{
int childId = 0;
var hiddenField = e.Item.FindControl("ChildID") as HiddenField;
if (null != hiddenField)
{
if (!string.IsNullOrEmpty(hiddenField.Value))
{
childId = Convert.ToInt32(hiddenField.Value);
}
}
if (childId > 0)
{
Response.Redirect("~/ChildDescription.aspx?ID=" + childId);
}
}
}
Hope this helps - if not, please post additional code for the "full picture" of what is happening, so we can see where else you might have a problem.
I think on the repeater you need to add
OnItemDataBound="MySponsoredChildrenList_ItemDataBound"
Not 100% sure, but could be the same for the ItemCommand.
--
In regards to obtaining the ChildID. Add a CommandArgument to the button in the repeater, and set it in the same way, <% Eval("ChildID") %>. This can the be obtained using e.CommandArgument.
Try this.. Add an attribute to item row
row.Attributes["onclick"] = string.Format("window.location = '{0}';", ResolveClientUrl(string.Format("~/YourPage.aspx?userId={0}", e.Item.DataItem)) );
or You can do like this also
<ItemTemplate> <tr onmouseover="window.document.title = '<%# Eval("userId", "Click to navigate onto user {0} details page.") %>'" onclick='window.location = "<%# ResolveClientUrl( "~/YourPage.aspx?userId=" + Eval("userid") ) %>"'> <td> <%# Eval("UserId") %> </td> </tr> </ItemTemplate>

How to pass in runtime a index of row for ListView?

I have an question, On my page i have a ListView control, I also have a button that has CommandArgument. I know i can read and find a control in the ListView as :
ListView.Items[i].FindControl("controlname");
and my button in ListView is like that
asp:Button ID="WisdomButton" runat="server" CommandName="UpdateWisdom" CommandArgument='<%# need my index for Item[i] to post here %>'
OnCommand="UpdateWisdom" Text="Update" />
I want to add index value in runtime to the CommantParameter, so when i go to the Function onCommand i will know exactly from what row[i] i Need to get my controls from ListView.
So my question is, how do i dinamicly add index of ListView.Rows[i] into CommmandArgument for the Button in runtime ?
Thanks in advance.
Check out the API
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listviewcommandeventargs.aspx
The ListViewCommandEventArgs item has an index, IE it is already available in the argument
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
int i = dataItem.DisplayIndex;
But from here you will have access to those controls
e.Item.FindConrol("controlName");
If you are calling the method a different way you could aways assign the index through an ItemDataBound Event
void MyListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
((Button)e.Item.FindControl("WisdomButton")).CommandArgument = ((ListViewDataItem)e.Item).DisplayIndex;
}
OR try something like this for giggles
<asp:Button runat="server" CommandArgument='<%# DisplayIndex %>'/>
// OR
<asp:Button runat="server" CommandArgument='<%# NextIndex() %>'/>
It might help to know a little bit more about what your are trying to do. If your end goal is to get any of the properties from your bound object you can just cast the dataItem from the ListViewCommandEventArgs of the ItemCommand event. You don't need to retain the index or call FindControl at all.
Here is an example of how to get the bound Customer object.
ListView
<asp:ListView runat="server" id="Customers" ItemCommand="Customers_ItemCommand">
<LayoutTemplate>
<ul>
<asp:placeholder runat="server" id="itemPlaceholder" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<asp:Button runat="server" id="Select" CommandName="Select" />
<%# Eval("Name")%>
</li>
</ItemTemplate>
</asp:ListView>
CodeBehind
public void Page_Load()
{
if (!Page.IsPostBack)
{
this.Customers.DataSource = GetCustomers();
this.Customers.DataBind();
}
}
public void Customers_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
if (e.Item.ItemType != ListViewItemType.DataItem)
return;
var customer = ((ListViewDataItem)e.Item).DataItem as Customer;
if (customer != null)
{
// Now work directly with the customer object.
Response.Redirect("viewCustomer.aspx?id=" + customer.Id);
}
}
}
Edit: In addtion when you cast the item to a ListViewDataItem, then you also expose a ((ListViewDataItem)e.Item).DataItemIndex property that might help you.

Categories