I have <telerik:RadGrid/>
inside this grid i have the following column contains button
<telerik:GridTemplateColumn >
<ItemTemplate>
<asp:Button ID="btnDelete" runat="server" Text="Delete"
CommandArgument='<%#Container.ItemIndex%>' OnCommand="btnDelete_Command">
protected void btnDelete_Command(object sender, CommandEventArgs e)
{
Telerik.Web.UI.GridDataItem item = gvAllDocuments.Items[int.Parse(e.CommandArgument.ToString())];
string FileName = item["documentFileName"].Text;
}
how I can add confirmation message before function btnDelete_Command executing ..
Do not use ItemIndex. It is just a row index of the grid. Instead, you want to set unique id inside DataKeyNames.
Ideally, you do not want to implement your own delete button, because telerik already has delete button which calls OnDeleteCommand automatically.
It is a prefer way of doing it for RadGrid.
<telerik:RadGrid ... OnDeleteCommand="RadGrid_DeleteCommand">
<MasterTableView DataKeyNames="xxxId" ...>
<Columns>
<telerik:GridButtonColumn
ButtonType="ImageButton"
ConfirmText="Are you sure you want to delete?"
CommandName="Delete"
ImageUrl="~/Images/Delete.png"
Text="Click to delete" UniqueName="Delete">
</telerik:GridButtonColumn>
</Columns>
...
</MasterTableView>
</telerik:RadGrid>
protected void RadGrid_DeleteCommand(object source, GridCommandEventArgs e)
{
int id = Convert.ToInt32(
e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["xxxId"]);
// Delete logic here.
}
Related
I'm trying to upload a file onchange event of the "Fileupload" control inside gridview.
Means when ever user uploads the file, there itself I needs to save the file content in DB.
So, I had mannually called the click event of the button control on the change of fileupload control But its throwing as like exception like "Invalid postback or callback argument...."
my gridview code :
<asp:GridView runat="server" ID="grd" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="StudentID" HeaderText="Student ID" />
<asp:BoundField DataField="StudentName" HeaderText="Name" />
<asp:TemplateField HeaderText="Upload">
<ItemTemplate>
<asp:FileUpload ID="FileUpload1" runat="server" EnableViewState="true" onChange="FileUploadCall(this)" />
<asp:Button ID="btnUpload" Text="Upload" runat="server" OnClick="Upload" Style="display: none" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
My script Code :
<script type="text/javascript">
function FileUploadCall(fileUpload) {
if (fileUpload.value != '') {
var a = $('#<%=grd.ClientID %>').find('[id*="btnUpload"]');
a.click();
}
}
</script>
My Hidden Button mannual click creation in cs file :
protected void Upload(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gvr = (GridViewRow)btn.Parent.Parent;
FileUpload lbleno = (FileUpload)gvr.FindControl("FileUpload1");
lbleno.SaveAs(Server.MapPath("~/Uploads/" + Path.GetFileName(lbleno.FileName)));
//lblMessage.Visible = true;
}
Your jquery code that gets the button to upload may be the reason.
Since you said you are using a gridview, so there could be multiple rows each having its own fileupload and button controls. You need to get the button control associated with this row in grid view. To get the associated button, you should be using the jquery code like below, since the associated button immediately follows the fileupload control.
if (fileUpload.value != '') {
var a = $(fileUpload).next("[id*='Button1']");
a.click();
}
The easiest way is to assign the onchange event from code behind so you can get the correct button easily. So create a RowDataBound event for the GridView.
<asp:GridView ID="grd" runat="server" OnRowDataBound="grd_RowDataBound">
Then in the RowDataBound method, use FindControl to locate and cast the FileUpload and the Button. In the method you can assign the change event to trigger a PostBack of the corresponding button.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//use findcontrol to locate the controls in the row and cast them
Button btn = e.Row.FindControl("btnUpload") as Button;
FileUpload fu = e.Row.FindControl("FileUpload1") as FileUpload;
//assign the button postback to the change of the fileupload
fu.Attributes.Add("onchange", "__doPostBack('" + btn.UniqueID + "','')");
}
}
Your implementations is fine only change:
a.click(); => a[0].click(); //important!!
and I hope no binding is happening in the postback:
if (!IsPostBack)
{
var list = new List<Student>();
list.Add(new Student() {StudentID = 1, StudentName = "111"});
list.Add(new Student() {StudentID = 2, StudentName = "222"});
grd.DataSource = list;
grd.DataBind();
}
I've tested it works totally fine!
I have an aspx page that has a gridview with 3 fields and one button "Update". When I click on the Update button I'll be redirected to another aspx page that has a form with more information about the entry in the grid view that was selected by clicking the button "Update". The form contains more fields and a button "Delete". When I click the button "Delete" I need to close the opened form and go back to the gridview and delete that entry. I'm using TemplateField to my gridview.
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField ShowHeader="False" HeaderText=" ">
<ItemTemplate>
<asp:Button ID="Btn_Update" Text="Update" runat="server" ButtonType="Button" CommandName="update" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ID" HeaderText="ID" />
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" />
</Columns>
</asp:GridView>
This is the code after I click the button "Delete" in the form to close it and go back to the gridview:
protected void btn_Delete_Click(object sender, EventArgs e)
{
#region Redirect to Page
Page.ClientScript.RegisterStartupScript(this.GetType(), "RefreshParent", "<script language='javascript'>RefreshParent()</script>");
Response.Write("<script>window.close();</" + "script>");
#endregion
ClearData();
}
How can I delete the row from the gridview after clicking the button "Delete" in the form? Thank you all
Here's some sample code so you'd get the idea. It's WPF + C#, not web, but you should get the drift. The idea is the same.
Your main program:
public delegate void DeleteRow(bool doDelete);
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
int selectedRow = 0;
public DeleteRow deleteRowDelegate;
public void ReportDelete(bool delete)
{
// Delete the row here.
}
public MainWindow()
{
InitializeComponent();
deleteRowDelegate += new DeleteRow(ReportDelete);
}
private void btnOK_Click(object sender, RoutedEventArgs e)
{
// Here, get the row number to selectedRow.
SecondaryWin win = new SecondaryWin(deleteRowDelegate);
win.ShowDialog();
// At this point, if DELETE was clicked in your secondary window, code would have executed ReportDelete() method.
}
}
And this would be your secondary window:
public partial class SecondaryWin : Window
{
DeleteRow callbackDel;
public SecondaryWin(DeleteRow callback)
{
InitializeComponent();
callbackDel = callback;
}
private void btnDel_Click(object sender, RoutedEventArgs e)
{
callbackDel.Invoke(true);
// Close the window
}
}
So in your main you register the ReportDelete() method to the DeleteRow delegate, and then pass it into your secondary window. I've passed it in the constructor, but you could use a different method if you so wishes.
Then in my secondary window you could call that delegate when you click the DELETE button, and exit that window.
Back in Main(), whenever the DELETE is clicked in your secondary window it will execute the code inside your ReportDelete() method where you could delete that particular row. Use selectedRow for this purpose.
I have two GridViews. The user can select a row from the first GridView and a list based on the GridView ID selected will display.
First Grid:
Second Grid:
Code for first GridView:
<asp:GridView style="width:75%"
ID="gvCVRT"
ShowHeaderWhenEmpty="true"
CssClass="tblResults"
runat="server"
OnSelectedIndexChanged="gridviewParent_SelectedIndexChanged"
OnRowDataBound="gvCVRT_RowDataBound"
DataKeyField="ID"
DataKeyNames="ChecklistID"
AutoGenerateColumns="false"
allowpaging="false"
AlternatingRowStyle-BackColor="#EEEEEE">
<HeaderStyle CssClass="tblResultsHeader" />
<Columns>
<asp:BoundField DataField="ChecklistID" HeaderText="ID" ></asp:BoundField>
<asp:CommandField ShowSelectButton="True" HeaderText="Select" />
<asp:BoundField DataField="ChecklistDate" HeaderText="Checklist Date" dataformatstring="{0:dd/MM/yyyy}"></asp:BoundField>
<asp:BoundField DataField="User" HeaderText="User" ></asp:BoundField>
<asp:BoundField DataField="Note" HeaderText="Note" ></asp:BoundField>
<asp:TemplateField HeaderText="Delete" ItemStyle-CssClass="tblRowDelete">
<ItemTemplate>
<asp:LinkButton ID="btnDelete"
runat="server" OnClientClick="event.stopPropagation()" OnClick="btnDeleteCVRT_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind:
protected void gvCVRT_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
lookupCVRT work = (lookupCVRT)e.Row.DataItem;
GridView gv = sender as GridView;
string checklistid = work.ChecklistID.ToString();
e.Row.Attributes.Add("ID", "gvCVRT_" + work.ID);
LinkButton btnDelete = (LinkButton)e.Row.FindControl("btnDelete");
btnDelete.CommandArgument = checklistid;
if (work.ID != null)
{
int index = gv.Columns.HeaderIndex("Select");
if (index > -1)
{
e.Row.Cells[index].Attributes.Add("class", "gvCVRTRow");
e.Row.Cells[index].ToolTip = "Click here to Edit Checklist";
e.Row.Cells[index].Attributes.Add("style", "color:blue;cursor:pointer;cursor:hand");
}
}
}
}
Code for gridviewParent_SelectedIndexChanged:
protected void gridviewParent_SelectedIndexChanged(object sender, EventArgs e)
{
List<lookupCVRT> workDetails = lookupCVRT.GetChecklistItemsByChecklistID(Company.Current.CompanyID, ParentID.ToString(), gvCVRT.SelectedDataKey.Value.ToString());
gvCVRTDetails.DataSource = workDetails;
gvCVRTDetails.DataBind();
FireJavascriptCallback("setArgAndPostBack ();");
}
Javascript:
$(".gvCVRTRow").off();
$(".gvCVRTRow").click(function (e) {
ShowAddEditCVRT(this, "Edit");
});
function ShowAddEditCVRT(sender, AddEdit) {
$("#divCVRTDetails").fadeIn(300);
}
Sorry its a lot of code but I wanted to show exactly what is happening. When I set the code to int index = gv.Columns.HeaderIndex("Select"); it goes into the javascript function ShowAddEditCVRT first, which tries to display the second grid divCVRTDetails. But I need to run the method gridviewParent_SelectedIndexChanged first because this binds the second grid with the ID selected from the first grid.
The only way I can get the second grid to bind first is to change the code to this: int index = gv.Columns.HeaderIndex("Checklist Date");.
So the user has to click on select first (to bind the grid) then click on the date cell to display the grid.
so my question is, is there anyway to run the gridviewParent_SelectedIndexChanged method before the javascript function gets called?
See the link below for more detail where I found this information.
http://www.codeproject.com/Questions/246366/run-javascript-from-side-server-in-asp-net-and-csh
You can add your javascript from the server side after you bind your gridview.
protected void Page_Load(object sender, EventArgs e) {
String script = #"<script language=""Javascript"">
$(".gvCVRTRow").off();
$(".gvCVRTRow").click(function (e) {
ShowAddEditCVRT(this, "Edit");
});
function ShowAddEditCVRT(sender, AddEdit) {
$("#divCVRTDetails").fadeIn(300);
}
</script>";
Page.RegisterClientScriptBlock("experiment", script);
gvCVRT.Attributes.Add("DataBound", "TestJScript()");
I believe this replaces your FireJavascriptCallback("setArgAndPostBack ();");
EDIT
I changed the code to better match what you provided and also where to put the code. I think it should go under page load. I also changed the gvCVRT.Attributes.Add to make it so the javascript runs when the gvCVRT is databound.
Answer to this is I called the javascript by using FireJavascriptCallback("myFunction();"); then just put the javascript code I needed into this function.
FireJavascriptCallback is a function:
protected void FireJavascriptCallback(string JSFunctionName)
{
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this.Page, this.Page.GetType(), "Callback", JSFunctionName, true);
}
How do I go about getting the selected value from the DropDownList in asp.Net using selectedIndexChanged with an update Panel? I've tried but when I add the AutoPostBack to my DropDownList, it sends me to an error page saying it cannot find the resource.(doesn't even hit my "selected_IndexChanged") I have the hiddenField being assigned the selected value.
Here is my DropDownList:
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel runat="server" ID="UpdatePanel1">
<ContentTemplate>
<asp:DropDownList runat="server" ID="ddlCaseFilesNew" DataSourceID="dsCaseFiles"
DataTextField="Display" DataValueField="FileID" OnPreRender="ddl_PreRender" Width="300px"
AutoPostBack="true" OnSelectedIndexChanged="ddlCaseFilesNew_SelectedIndexChanged" Visible="False">
<asp:ListItem>Item 1</asp:ListItem>
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlCaseFilesNew" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
When I click on a value inside the DropDownList it sends me to a "cannot find resource" page. I have no idea why. It doesn't even touch my "onSelectedIndexChanged"
<script runat="server">
protected void ddlCaseFilesNew_SelectedIndexChanged(object sender, EventArgs e)
{
hidNewCaseFile.Value = ddlCaseFilesNew.SelectedItem.Value;
}
</script>
In your SelectedIndex function, use
string sValue = ((DropDownList)sender).SelectedValue;
Since it's in an update panel, you likely won't have access to it via the designer (this.DdlId).
Based on your comment in the OP, this is likely what you need:
protected void ddlCaseFilesNew_SelectedIndexChanged(object sender, EventArgs e)
{
hidNewCaseFile.Value = ((DropDownList)sender).SelectedValue;
}
You also need to move your hidden field into the ContentTemplate.
Use:
protected void myDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
var res = this.myDropDownList.SelectedValue;
}
Or:
protected void myDropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
var ddl = sender as DropDownList;
var res = ddl.SelectedValue;
}
Edit 1
You need to understand that the partial page rendering occurs for all controls inside an UpdatePanel, in your case, you are trying to set the Value property of hidNewCaseFile control which does not appear to be inside the UpdatePanel therefore, its value will never get updated
i am stuck with this error since last few hours.. i dont know what am i doing wrong here..
<script type="text/javascript">
function viewProfile(index)
{
var GridID = document.getElementById("PersonGridView");
var row=GridID.rows[parseInt(index)+1];
window.open('detailsid.aspx?'+row);
}
</script>
<Columns>
<asp:BoundField HeaderText="First Name" DataField="FirstName" />
<asp:BoundField HeaderText="Last Name" DataField = "LastName" />
<asp:BoundField HeaderText="HomePhoneNumber" DataField="HomePhoneNumber" />
<asp:TemplateField HeaderText="ViewDetails">
<ItemTemplate>
<asp:Button ID="Deatils" runat="server" Text="Details" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:Button ID="Modify" runat="server" Text="Modify" />
<asp:Button ID="Delete" runat="server" Text="Delete" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#CCCC99" />
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
<SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
</div>
</form>
<p> Code Behind :
protected void PersonGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();
Button btnDetails = (Button)FindControl("Details");
Button btnModify = (Button)FindControl("Modify");
Button btnDelete = (Button)FindControl("Delete");
btnModify.CommandName = "Modify";
btnDelete.CommandName = "Delete";
btnDetails.CommandName = "Details";
btnDelete.CommandArgument = btnModify.CommandArgument = string.Format("{0}", ID);
btnDetails.Attributes["onclick"] = string.Format("viewProfile({0}); return false;", ID);
}
}
Change
var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();
if (e.Row.RowType == DataControlRowType.DataRow)
{
to
if (e.Row.RowType == DataControlRowType.DataRow)
{
var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();
i.e. extract the DataKeys only when the row is of DataRow and not for Header/Footer etc.
Is this the line that's throwing the error?:
var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();
This line is referencing an array item by index in two different places, so you'll need to do a little debugging to determine which one is the problem. Basically, either PersonGridView.DataKeys[] doesn't have an index which matches e.Row.RowIndex or that item doesn't have an index which matches "ID". You'll need to either step through a debugger to examine those values at runtime or toss in some debugging code (Response.Write statements and such to examine values) to see what's going on.
One common error is that the DataGridView is running this code on non-data rows. Header, footer, etc. You can expand the scope of the if statement to address that. Reference the indexes within the conditional rather than outside of it.
Edit: (In response to your comment below)
Is btnDetails set to an instance of an object? I'm guessing it isn't. You'll need to continue the debugging and see if the control you're trying to find is actually there. I notice that it's in a separate ItemTemplate and TemplateField from the other buttons. Is that causing an issue perhaps? I'm not entirely familiar with these server controls so I'm not sure off-hand.
I should take a moment to point out that your code here is very fragile. The problems you've been experiencing are the result of this. You're referencing arrays by indexes manually, including the use of a "magic string" to reference them. You might want to toss in some error checking for that. You're also casting and later using objects without checking if they exist first. FindControl can very easily return a null reference, such as when the control isn't found.
Throwing in tons of error checking is kind of part of the reality of using these web forms controls and their old data binding methods. A lot of extra code, but that's how it goes with these controls and directly binding to weakly-typed DataSets and such.