Handle multiple delete events from grid with single events handlers asp.net - c#

I have two grid which contains delete button and I am using RadAjaxManager which will fire ajax request from client side to server side OnajaxRequest which contain event handlers and that event handler will call my delete event like below:
<telerik:RadAjaxManager ID="RadAjaxManager2" runat="server" meta:resourcekey="RadAjaxManager1Resource1" OnAjaxRequest="RadAjaxManager2_AjaxRequest">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="RadAjaxManager2">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="Grid1" />
<telerik:AjaxUpdatedControl ControlID="Grid2" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
<telerik:RadGrid ID="Grid1" runat="server">
---
---
<telerik:GridTemplateColumn HeaderText="Action" UniqueName="Action" HeaderStyle-Width="130px">
<ItemTemplate>
<asp:ImageButton runat="server" ID="Remove1" Text="Delete" OnClientClick='<%# Eval("Id", "javascript:return DeleteData(\"{0}\");") %>' />
</ItemTemplate>
</telerik:GridTemplateColumn>
<telerik:RadGrid ID="Grid2" runat="server">
---
---
<telerik:GridTemplateColumn HeaderText="Action" UniqueName="Action" >
<ItemTemplate>
<asp:ImageButton runat="server" ID="Remove2" Text="Delete" OnClientClick='<%# Eval("Id", "javascript:return DeleteData(\"{0}\");") %>' />
</ItemTemplate>
</telerik:GridTemplateColumn>
function DeleteData(Id) {
var ajaxManager = null;
var action = 'Remove';
ajaxManager = $find("ctl00_cphMain_RadAjaxManager2");
var arg = action + "," + Id; //Remove,1(1 indicates id of record to remove from grid)
ajaxManager.ajaxRequest(arg);This line will fire below method.
}
public event EventHandler RemoveEvent;
protected void RadAjaxManager2_AjaxRequest(object sender, AjaxRequestEventArgs e)
{
var argument = (e.Argument);
var stringArray = argument.Split(",".ToCharArray());//[0]="Remove",[1]=1
if (stringArray[0] == "Remove")
{
RemoveEvent(stringArray[1], null);
}
}
After this it will call this:
protected void Page_Load(object sender, EventArgs e)
{
this.RemoveEvent += Remove1_Click;
this.RemoveEvent += Remove2_Click;
if (!IsPostBack)
{
}
}
protected void Remove1_Click(object sender, object obj)
{
}
protected void Remove2_Click(object sender, object obj)
{
}
Problem here is both this events are calling but I just want to call individual delete events on click of Remove1 and Remove2 buttons.

You do not need to subscribe to events in your code-behind i.e. no need of this.RemoveEvent+=. Instead write a single method called RemoveRecord(buttonId, recordId). I have explained this approach in a step-by-step manner as below.
First change the markup for OnClientClick. Note that we will be passing the Id of the record to delete as well as the server-side id of the button being clicked to the JavaScript function DeleteData.
OnClientClick='<%# Eval("Id", "DeleteData('{0}', 'Remove1'); return false;") %>'
OnClientClick='<%# Eval("Id", "DeleteData('{0}', 'Remove2'); return false;") %>'
Change the JavaScript Delete method. Note that we are now passing the server-side button id, so that in code-behind we can easily know which button was clicked.
function DeleteData(Id, buttonId) {
var ajaxManager = null;
ajaxManager = $find("<%=RadAjaxManager2.ClientID%>");
var arg = buttonId + "," + Id; //Remove1,1 (1 indicates id of record to remove from grid)
ajaxManager.ajaxRequest(arg);//This line will fire below method.
}
In code behind, include a single RemoveRecord method and there is no need of creating event handlers as you have done in your original code. So you should remove the following methods from your original code: Remove1_Click and Remove2_Click and also remove the code in Page_Load that subscribes to click events.
protected void RadAjaxManager2_AjaxRequest(object sender, AjaxRequestEventArgs e)
{
var stringArray = e.Argument.Split(",".ToCharArray());//[0]="Remove1" or "Remove2",[1]=id of record to delete
RemoveRecord( stringArray[0], stringArray[1]);
}
//the method below will delete data
private void RemoveRecord( buttonId, recordId)
{
if(buttonId== "Remove1")
{
//code to delete record with id of recordId
}
else if ( buttonId == "Remove2")
{
//code to delete record with id of recordId
}
}
Another Approach
If you have to have RadAjaxManager2_AjaxRequest in parent page and delete methods in child page, then add the following code at appropriate places as mentioned in their titles. But please note that the markup changes and JavaScript function changes mentioned in above approach also apply to this approach.
In Parent Page (just outside the class)
public class RemoveEventArgs : EventArgs
{
public RemoveEventArgs ( string buttonId, string recordId)
{
this.ButtonId = buttonId;
this.RecordId = recordId;
}
public string ButtonId {get;set;}
public string RecordId {get;set;}
}
Also, in same parent page change the method RadAjaxManager2_AjaxRequest to what is given below.
In Parent Page (change this existing method)
protected void RadAjaxManager2_AjaxRequest(object sender, AjaxRequestEventArgs e)
{
var stringArray = e.Argument.Split(",".ToCharArray());//[0]="Remove1",[1]=1 OR [0]="Remove2", [1] = 212
if (stringArray[0] == "Remove1" || stringArray[0] == "Remove2")
{
if(RemoveEvent!=null)
{
RemoveEvent(this, new RemoveEventArgs(stringArray[0], stringArray[1]));
}
}
}
In Child Page (change existing methods)
protected void Remove1_Click(object sender, RemoveEventArgs obj)
{
if( obj!=null && obj.ButtonId == "Remove1")
{
string recordId = obj.RecordId;
//write your code for deleting
}
}
protected void Remove2_Click(object sender, RemoveEventArgs obj)
{
if( obj!=null && obj.ButtonId == "Remove2")
{
string recordId = obj.RecordId;
//write your code for deleting
}
}

you simply just use the RadGrid_ItemCommand and pass the command argument with del button and change the command name for both remove her's a sample code for
<telerik:GridTemplateColumn HeaderText="Actions">
<ItemTemplate>
<asp:ImageButton ID="Button3" Style="width: 14px" Height="14px" ImageUrl="~/Images/Erase.png" runat="server" Text="Delete1" OnClientClick="return confirm('Are you sure you want to delete this item?');" CommandName="Delete1" CommandArgument='<%# Eval("Pid") %>' />
&nbsp &nbsp
<asp:ImageButton ID="Button3" Style="width: 14px" Height="14px" ImageUrl="~/Images/Erase.png" runat="server" Text="Delete2" OnClientClick="return confirm('Are you sure you want to delete this item?');" CommandName="Delete2" CommandArgument='<%# Eval("Pid") %>' />
</ItemTemplate>
</telerik:GridTemplateColumn>
protected void RadGrid1_ItemCommand(object sender, GridCommandEventArgs e)
{
if (e.CommandName == "Delete1")
{
}
if (e.CommandName == "Delete2")
{
}
}

Related

Dynamically give Id to button, Commandargument send value

Here is my part of Shop.aspx code:
<% foreach(var item in items){ %>
...
<asp:Button id="btnBuy" runat="server" class="btn" Text="Buy" OnClick ="btnBuy_Click" CommandArgument='<%#Eval("item.id") %>' />
<% } %>
I've got a loop where I create few buttons to my shopping items, and I need them to have id of my item
protected void btnBuy_Click(object sender, EventArgs e)
{
int itemId = Convert.ToInt32(btnBuy.CommandArgument);
}
On click i need to have id of the item/button clicked, to save them later in my database.
Problem -
When i click on button btnbuy.CommandArgument is "".
It's wrong: you wrote c#in asp style. You have to use a Repeater and then you can manage ItemCommand for every button click.
Aspx
<asp:Repeater ID="myRepeater" runat="server" OnItemCommand="myRepeater_ItemCommand">
<ItemTemplate>
<asp:Label id="myLbl" runat="server" Text='<%# ((Item)(Container.DataItem)).ProductName %>'/>
<asp:Button id="btnBuy" runat="server" CssClass="btn" Text="Buy" CommandName="Click" CommandArgument='<%# ((Item)(Container.DataItem)).ProductId %>' />
</ItemTemplate>
</asp:Repeater>
c# (eg. OnLoad)
List<Item> myCollection = ...; // get list of items
myRepeater.DataSource = myCollection;
myRepeater.DataBind();
...
protected void myRepeater_ItemCommand(Object sender, RepeaterCommandEventArgs e)
{
if(e.CommandName == "Click")
{
int idRecord = Convert.ToInt32(e.CommandArgument);
// do something using idRecord or
// get sender properties: ((Button)e.CommandSource).Text
}
}

how to get image url on click in repeater

i want to get image url on clicking the image from database in repeater
my database contains(id,url)
my repeater code is:
<asp:Repeater runat="server" ID="repeater" >
<ItemTemplate >
<asp:ImageButton runat="server" Width="200px" Height="200px" ImageUrl='<%#Eval("url") %>' OnCommand="Image_Click" CommandName="ImageClick" CommandArgument='<%#Eval("url") %>' />
</ItemTemplate>
</asp:Repeater>
my .cs code is
protected void Image_Click(object sender, CommandEventArgs e)
{
if (e.CommandName == "ImageClick")
{
string a=e.CommandArgument.tostring();
responce.write(a);
}
}
you can do in ImageClick
((ImageButton)sender).ImageUrl
to get the url of the clicked button
Cast sender to ImageButton and read its ImageUrl property.
Also, is there a reason you are using command instead of handling ImageButtons click event?
Both Vladimir and Guigui answers are prefer way of accessing URL of an image button.
If you also want ID value in addition to URL, you can store multiple values into CommandArgument separated by comma.
<asp:ImageButton runat="server"
ImageUrl='<%#Eval("url") %>'
OnCommand="Image_Command"
CommandName="ImageClick"
CommandArgument='<%# Eval("Id")%> + "," + Eval("url") %>' />
protected void Image_Command(object sender, CommandEventArgs e)
{
if (e.CommandName == "ImageClick")
{
string[] commandArgs = e.CommandArgument.ToString()
.Split(',');
string id = commandArgs[0];
string url = commandArgs[1];
}
}

c# Why does my page / user control only support one event handler

I have 2 events that I want to fire from a user control back to it's parent.
"UserSelected" and "NoUsersSelected"
One fires when a user is selected and the other fires when all the users have been removed.
My problem is "UserSelected" works, but "NoUsersSelected" fails... In the code snippets below, I have commented the line that fails.
UPDATE:
When I comment all code relating to the first event handler, the 2nd one starts working.
Here is the code on my child (user) control:
public event EventHandler UserSelected;
public event EventHandler NoUsersSelected;
protected virtual void onUserSelected(System.EventArgs e)
{
if (UserSelected != null) UserSelected(this, e);
}
protected virtual void onNoUsersSelected(System.EventArgs e)
{
**###** PROBLEM ! - NoUsersSelected is always null so doesn't fire event **###**
if (NoUsersSelected != null) NoUsersSelected(this, e);
}
And to raise the events, I use buttons inside a GridView TemplateField:
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnSelect" CommandArgument='<%# Eval("UserID") %>' CommandName="SelectUser" ToolTip="Select User" runat="server" UseSubmitBehavior="false" CssClass="GridBtn_Select" CausesValidation="false" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnDelete" CommandArgument='<%# Eval("UserID") %>' CommandName="DeleteUser" ToolTip="Delete User" runat="server" OnClientClick="javascript:if(!confirm('Are you sure?')) return false;" UseSubmitBehavior="false" CssClass="GridBtn_Delete" CausesValidation="false" />
</ItemTemplate>
</asp:TemplateField>
And here is the code behind for these buttons:
if (e.CommandName == "SelectUser")
{onUserSelected(System.EventArgs.Empty);}
and...
if (e.CommandName == "DeleteUser")
{ //this is where I remove the user from the grid...
if (gridUsers.Rows.Count < 1)
{onNoUsersSelected(System.EventArgs.Empty);}
.
On the parent page that hosts the user control:
protected void Page_Load(object sender, EventArgs e)
{
//Bind to the event on child control
GridAdvertiserUsers.UserSelected += UserSelected_EventHandler;
GridAdvertiserUsers.NoUsersSelected += NoUsersLinked_EventHandler;
}
and the functions that the events call:
void UserSelected_EventHandler(object sender, EventArgs e)
{ //do stuff here }
void NoUsersLinked_EventHandler(object sender, EventArgs e)
{ //Do other stuff }
UPDATE:
When onUserSelected is called, both Events seem to have their methods wired up correctly
But when onNoUserSelected is called, they are both null:

How can I dynamically do write a value into a function call?

<asp:LinkButton class="uibutton normal submit" ID="LinkButtonMAR"
OnClick="MarkClientNoteRead(<%# Eval("NoteID") %>)" runat="server">
Mark as Read</asp:LinkButton>
This is all within a repeater that will return a list of notes. I want to grab the NoteID and throw this into the OnClick="MarkClientNoteRead()" method call.
Is this possible?
You could use the CommandArgument:
<asp:LinkButton class="uibutton normal submit"
ID="LinkButtonMAR"
CommandName="MarkRead"
CommandArgument='<%# Eval("NoteID") %>'
Text="Mark as Read"
OnCommand="MarkClientNoteRead" runat="server" />
protected void MarkClientNoteRead(Object sender, CommandEventArgs e)
{
int NoteID = int.Parse(e.CommandArgument.ToString());
}
Note that you need to handle the Command event instead of the Click event.
Another more convoluted way would be:
<asp:LinkButton class="uibutton normal submit" ID="LinkButtonMAR"
OnClick="LinkButtonMAR_Click" runat="server">Mark as Read
</asp:LinkButton>
<asp:HiddenField ID="NoteID" runat="server" Value='<%# Eval("NoteID")%>' />
Code Behind:
protected void LinkButtonMAR_Click(object sender, EventArgs e)
{
LinkButton thisLinkBUtton = (LinkButton)sender;
// substitute appropriate object for the GridViewRow below
GridViewRow thisGridViewRow = (GridViewRow)thisLinkBUtton.Parent.Parent;
HiddenField hdnNoteID = (HiddenField)thisGridViewRow.FindControl("NoteID");
// run your update code...
}
I've used this, but it bothers me having to use Parent.Parent. Plus, I was needing other bits of data from the same row.

Handling control events from Repeater footer

Assuming I have the following repeater.
<asp:Repeater ID="MyRepeater" runat="server" onitemdatabound="MyRepeater_ItemDataBound">
<FooterTemplate>
</table>
<asp:Button ID="btnPrevious" runat="server" Text="<" />
<asp:Label ID="lblCurrentPage" runat="server" Text="<%# PagingStatus() %>" />
<asp:Button ID="btnNext" runat="server" Text=">" />
</FooterTemplate>
</asp:Repeater>
How can I handle the click events from btnPrevious and btnNext?
I have tried the following:
protected void MyRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Button btnPrevious = (Button)e.Item.FindControl("btnPrevious");
Button btnNext = (Button)e.Item.FindControl("btnNext");
if (btnPrevious != null)
btnPrevious.Click += btnPrevious_Click;
if (btnNext != null)
btnNext.Click += btnNext_Click;
}
But this has failed (The event is never raised)..
You can use them in the same way you would use a normal button event handler eg:
Html:
<asp:Button ID="btnNext" runat="server" CommandArgument="<%=Id%>" onclick="Button_OnClick" Text=">" />
Code:
protected void Button_OnClick(object sender, EventArgs e)
{
Button button = sender as Button;
if(button != null)
{
string commandArg = button.CommandArgument;
//Do Work
}
}
The you can use the command argument to find out which button was clicked.
Hope this helps.
I would suggest using the ItemCommand event of the repeater. You still have to add the commands to your buttons though. Like this:
<asp:Button ID="btnPrevious" runat="server" Text="<" CommandName="Previous"/>
protected void MyRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if(e.CommandName.ToLower().Equals("previous")) {
//go back
}
else
{
//go forward
}
}

Categories

Resources