ItemCommand event doesn't fire with repeater control - c#

I am building a website whereby people, before checking out of the shopping cart (and transferring to the payment iframe) can select which items from the shopping cart list to delete. The results from the shopping card are listed in a Repeater control. There is a Button in the Repeater which deletes a record from the database (used LINQ to SQL to do that.)
The problem is that the ItemCommand event doesn't fire when i click the button. I tried response.write(test) and it still would not work.
It is as if the repeater cannot interact with the commands. It does render the results though.
<asp:Repeater ID="RepeaterKoshnichka"
runat="server" OnItemCommand="RepeaterKoshnichka_ItemCommand"
DataSourceID="LinqDataSource1">
<ItemTemplate>
<tr>
<td background="images/message-bar.gif">
<div class="message_head" style="float:left"><cite>Производ: <asp:Label ID="lblProizvod" CssClass="red_tx" Text='<%# Eval("Proizvod") %>' runat="server"></asp:Label> / Тип на Претплата: <asp:Label ID="lblPretplata" runat="server" Text='<%# Eval("Tip") %>' CssClass="red_tx"></asp:Label></cite></div>
<div class="message_head" style="float:right"><cite>Цена: <asp:Label ID="lblCena" CssClass="red_tx" Text='<%# Eval("Cena") %>' runat="server"></asp:Label>
<asp:Button ID="Button2" CssClass="main_tx" CommandName="Delete" CommandArgument='<%# Eval("NDetID") %>' runat="server" Text="Отстрани" /></cite>
</div>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
protected void RepeaterKoshnichka_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Delete")
{
if (Request.Form[e.CommandArgument.ToString()] != null)
{
if (Page.User.Identity.IsAuthenticated)
{
var nar = new DataClasses1DataContext();
Guid detnar = new Guid(e.CommandArgument.ToString());
var query = from c in nar.Naracka_Dets
where c.NDetID == detnar
select c;
foreach (var c in query)
{
nar.Naracka_Dets.DeleteOnSubmit(c);
}
nar.SubmitChanges();
lblSuma.Text = ((Button)e.CommandSource).ToString();
}
}
}
}

Likely an <asp:GridView> would be a better server control for what you're working on.
As an aside, consider making a small change to your code. To help make it more readable, combine your 3 conditions into one if:
if (e.CommandName == "Delete" &&
Request.Form[e.CommandArgument.ToString()] != null &&
Page.User.Identity.IsAuthenticated)
{
//delete things.
}

If you are not tied to using a Repeater you should switch to DataGrid and use a ButtonColumn for this feature - it will make life easier for you handling Item events.

Related

OnClick Event for panel which is inside a repeater

<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)

jQuery is not finding Asp.net repeater alternating item

I have a repeater on my webforms page, with a list bounded to it. while binding the list, I also attach a data-id attribute to the tr. The problem is I need to use that id in a web service call from jQuery, I am testing whether I can get the id by logging the data-id attribute value when I click on a button from the repeater item, but from the looks of things, it only logs the Item and not the Alternating item.
Button one, three and five gets log every time I click them but when I click on button two and button four, nothing gets logged in the console. See code below.
Repeater Template
<asp:Repeater runat="server" ID="rptList" OnItemDataBound="rptList_OnItemDataBound">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr runat="server" id="trList">
<td runat="server" id="tdList"></td>
<td runat="server" id="tdBtnRemove">
<asp:Button runat="server" ID="btnRemove" CssClass="btnRemove" Text="Remove" OnClientClick="return false;"/></td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr runat="server" id="trList">
<td runat="server" id="tdList"></td>
<td runat="server" id="tdBtnRemove">
<asp:Button runat="server" ID="btnRemove" Text="Remove" OnClientClick="return false;"/></td>
</tr>
</AlternatingItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
List item
List<string> listObj = new List<string>(){"one", "two", "three", "four", "five"};
protected void rptList_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
string listItem = (string) e.Item.DataItem;
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
HtmlTableRow trList = (HtmlTableRow)e.Item.FindControl("trList");
trList.Attributes.Add("data-id", listItem);
HtmlTableCell tdList = (HtmlTableCell)e.Item.FindControl("tdList");
tdList.InnerHtml = listItem;
}
}
jQuery button click method:
$(".btnRemove").click(function () {
var dataAttributVal = $(this).closest("tr");
var datA = dataAttributVal.data('id');
console.log(datA);
});
Console result:
As stated in the comments, your AlternatingItemTemplate misses the CssClass="btnRemove" attribute.
For this reason your $(".btnRemove").click(... binding does not target the buttons in your AlternatingItemTemplate

Get selected product from a datalist in visual studio and SQL

Im trying to learn asp and C# and trying to make a webshop.
I have a working dataset and datalist
<asp:DataList ID="DataList1" runat="server" DataKeyField="ID" DataSourceID="ObjectDataSource1" RepeatDirection="Horizontal" CellSpacing="10">
<ItemTemplate>
<asp:Image ImageUrl='<%# Eval("PicURL") %>' runat="server" ID="PicURLImage" Width="150px" /><br />
<asp:LinkButton ID="AddProduct" Text='<%# Eval("ProductName") %>' runat="server" OnClick="AddProduct_Click"></asp:LinkButton><br />
</ItemTemplate>
</asp:DataList>
I want to press this linkbutton and then It eventually should add this product to a shoppingcart. But right now I just need help to get the selected product row from the datalist that is using a datasource that is connected to the database.
When I click the link I want to execute this code:
Data.DataSet1.ProductDataTable pTable = new Data.DataSet1TableAdapters.ProductTableAdapter().GetDataByCategory();
protected void AddProduct_Click(object sender, EventArgs e)
{
// Add product to the shopping cart
//Class //method
ShoppingCart.Instance.AddItem(THIS IS HE QUESTION I NEED HELP WITH!);
// Redirect the user to view their shopping cart
Response.Redirect("ViewCart.aspx");
}
public void AddItem(int productId)
{
// Create a new item to add to the cart
CartItem newItem = new CartItem(productId);
// If this item already exists in our list of items, increase the quantity
// Otherwise, add the new item to the list
if (Items.Contains(newItem))
{
foreach (CartItem item in Items)
{
if (item.Equals(newItem))
{
item.Quantity++;
return;
}
}
}
else
{
newItem.Quantity = 1;
Items.Add(newItem);
}
}
Do you guys need more information? Do you have any tips or suggestions? Im stuck >__<
Here is how I would do this.
add CommandName attribute to your button (you will not longer need the OnClick event handler for the button) and add event handler for ItemCommand on DataList:
<asp:DataList ID="DataList1" runat="server" DataKeyField="ID" DataSourceID="ObjectDataSource1" RepeatDirection="Horizontal" CellSpacing="10" OnItemCommand="Item_Command">
<ItemTemplate>
<asp:Image ImageUrl='<%# Eval("PicURL") %>' runat="server" ID="PicURLImage" Width="150px" /><br />
<asp:LinkButton CommandName="AddProduct" ID="AddProduct" Text='<%# Eval("ProductName") %>' runat="server" OnClick="AddProduct_Click"></asp:LinkButton><br />
</ItemTemplate>
</asp:DataList>
Change your c# to define Item_Command
void Item_Command(Object sender, DataListCommandEventArgs e)
{
if (e.CommandName == "AddProduct")
{
// e.Item.ItemIndex is the selected index
// DataList1.DataKeys[e.Item.ItemIndex] will return the product id
}
}
Also you can refer to MSDN for further details.
protected void Btn_Command(object sender, CommandEventArgs e)
{
DataListItem dli = (DataListItem)(sender as Control).Parent.Parent;
int indx = dli.ItemIndex;
}

Firing different linkbuttons in a Repeater and saving the value of each in an arraylist

Im using a repeater to display some products in an online shop for a school project. This is how the front end looks with the repeater
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="rptList_ItemCommand">
<ItemTemplate>
<span style="float:left; padding:25px;" class="backgrnd">
<asp:ImageButton ID="imgProd" runat="server" style="width:150px; height:150px;" ImageUrl='<%# DataBinder.Eval(Container.DataItem, "productImg")%>' CommandArgument='<%# DataBinder.Eval(Container.DataItem, "productID")%>' CommandName="ViewIndividProd"/><br />
<p style="clear:left;">
<asp:Label ID="lbName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "productName")%>' /><br />
<asp:Label ID="lbUnitPrice" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "unitPrice")%>'/><br />
<asp:Label ID="lbRatings" runat="server" Text=''>Ratings</asp:Label><br />
<asp:LinkButton ID="linkCart" runat="server" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "productID")%>' CommandName="AddToCart">Add to Cart</asp:LinkButton>
</p>
</span>
</ItemTemplate>
</asp:Repeater>
As you can see I've added on the OnItemCommand in the Repeater tag so that this is invoked whenever one of the buttons(image/link) is fired. That works perfectly fine for both commandname AddToCart and ViewIndividProd. However, i want to store the the productid of a specific item that was invoked by the particular button. In my case now, it only stores ONE productid in the arraylist at a time and 'forgets' the productid that was stored previously when another linkbutton is clicked.
Question How do i make it such that everytime a linkbutton in the repeater is fired, it remembers the productid pertaining to the linkbutton that was fired and save these ids into the arraylist?
This is how the back end looks
ArrayList cart = new ArrayList();
protected void rptList_ItemCommand(object sender, RepeaterCommandEventArgs e) {
if (e.CommandName == "ViewIndividProd") {
Session["productID"] = e.CommandArgument.ToString();
Response.Redirect("IndividProduct.aspx");
}
if (e.CommandName == "AddToCart") {
string prodid = e.CommandArgument.ToString();
cart.Add(prodid);
Session["ShoppingCart"] = cart;
Response.Redirect("IndividCat.aspx");
}
msg.Text = "Shopping cart: " + String.Join(",", cart.ToArray());
}
Your feedback would be much appreciated.
You need to understand the Asp.net Page life cycle.
A new instance of your Page object is created on every request.
Values from your input are populated into it.
Your array list is getting recreated every time.
If you want the values to persist, you will have to store your arraylist in the ViewState or the Session
Refer: How to: Save Values in View State
void Page_Load(object sender, EventArgs e)
{
if (ViewState["arrayListInViewState"] != null)
{
PageArrayList = (ArrayList)ViewState["arrayListInViewState"];
}
else
{
// ArrayList isn't in view state, so we need to create it from scratch.
PageArrayList = CreateArray();
}
// Code that uses PageArrayList.
}
We can store comma separated or JSON value in either Session or hidden variable (If you are on the same page and opening new page in different tab then we can use hidden variable also). So every time an button has been click we can append the product id.

How I use the ItemCommand Event for my ListView in my ASP.NET Application

I have a ASP.NET Application with a ListView. In every Row in my ListView I have a LinkButton that open a new webform "Benutzer.aspx". my Problem is that I don't get the Index of this Row. I use the ItemCommand Event but it not work :(
Here my Code:
ASPX:
...
<ItemTemplate>
<tr runat="server">
<td align="left" ><asp:Label ID="Label1" Text='<%# Eval("Benutzer") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label2" Text='<%# Eval("eMail") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label3" Text='<%# Eval("Vorname") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label4" Text='<%# Eval("Nachname") %>' runat="server" /></td>
<td align="left"><asp:Label ID="Label5" Text='<%# Eval("Telefon") %>' runat="server" /></td>
<td align="left"><asp:LinkButton runat="server" Text="Anzeigen" CommandName="Anzeigen" OnCommand="ListView1_ItemCommand" CommandArgument="myArguments"></asp:LinkButton></td>
</tr>
</ItemTemplate>
...
cs file:
...
protected void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "Anzeigen")
{
Label lbText = (Label)e.Item.FindControl("Label2");
string email = lbText.Text;
Session["email"] = email;
Response.Redirect("Benutzer.aspx");
}
}
...
What is the matter :(
tarasov
Try this:
First you need to have the index of the button. So in the html code add this in the CommandArgument of the button to get the index:
CommandArgument='<%# Container.DataItemIndex %>'
Then in the codebehind:
if (e.CommandName == "Anzeigen")
{
Label lbText = ListView1.Item[e.CommandArgument].FindControl("Label2");
string email = lbText.Text;
Session["email"] = email;
Response.Redirect("Benutzer.aspx");
}
Hope I Helped
You cannot find the control because it is contained in the child control collection of another server control:
<tr runat="server">
You need to try to find the control recursively:
Take a look
Better way to find control in ASP.NET
Or you can use this extension method:
public static class ControlExtensions
{
public static Control FindControlRecursively(this Control control, string targetControlID)
{
if (control == null)
{
return null;
}
var ctrl = control.FindControl(targetControlID);
if (ctrl == null)
{
foreach (Control child in control.Controls)
{
ctrl = FindControlRecursively(child, targetControlID);
if (ctrl != null)
{
break;
}
}
}
return ctrl;
}
}
Usage:
var ctrl = e.Item.FindControlRecursively("your control ID");
The code you have furnished is simply fine... "just remove the 'CommandArgument' from your listview property , bcoz..its already have the dataindex you are looking for. By specifying a command argument you are overriding the default one.
So just remove the command argument and your code will work fine... :)
I am a VB programmer Check this method may b it gives you some idea
after binding the list with datasource, In the itemCommand do this
Dim <sometext> As Label = TryCast(e.Item.FindControl("Anzeigen"), Label)
If e.CommandName = "Anzeigen" Then
'do what ever you like
'also you can use <sometext> if you want to extract data from list
'simply use <sometext>.<whatproperty>, you can also store it in sessions like the email you are using.
Session("email") = email
Response.Redirect("Benutzer.aspx");
End If
let me know if it helps you solve your problem.
This is the HTML, then build the OnItemCommand.
<asp:ListView ID="lvFiles" runat="server" DataKeyNames="FileName" OnItemCommand="lvFiles_ItemCommand">
<ItemTemplate>
<tr runat="server">
<td style="width:80px">
<asp:LinkButton runat="server"
ID="SelectEmployeeButton"
Text="Download File"
CommandName='<%#Eval("FileName")%>'
CommandArgument='<%#Eval("FileName")%>' />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
Here is the code behind...
protected void lvFiles_ItemCommand(object sender, ListViewCommandEventArgs e)
{
string v = e.CommandArgument.ToString();
}

Categories