locked
Injecting javascript into gridview buttonfield RRS feed

  • Question

  • User121806066 posted

     I found some code to inject javascript into a linkbutton placed inside a templatefield, and it works great, but the linkbutton doesn't work right. I have a buttonfield doing the same thing and it works fine, but I can't figure out how to access it to add some javascript for the onclientclick.

    Any help would be appreciated..

    <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Manage.aspx.cs" Inherits="Manage" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="LoggedInContent" Runat="Server">
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="id" DataSourceID="ObjectDataSource1" CssClass="FileGrid" AllowSorting="True" OnRowCommand="GridView1_RowCommand" OnRowDataBound="GridView1_RowDataBound">
            <Columns>
                <%-- this one javascript works, but function doesnt --%>   
                <asp:TemplateField HeaderText="Delete">
                    <ItemTemplate>
                        <asp:LinkButton ID="LinkButton1" CommandName="SoftDelete" runat="server" Text="Delete2" />
                    </ItemTemplate>
                </asp:TemplateField>
                <%-- this one function works, but javascript doesnt --%>
                <asp:ButtonField ShowHeader="True" Text="Delete" CommandName="SoftDelete"  />
                <asp:HyperLinkField HeaderText="Link" Text="Download" DataNavigateUrlFields="dataFileName" DataNavigateUrlFormatString="/Files/{0}" />
                <asp:BoundField DataField="fileName" HeaderText="File" SortExpression="fileName" />
                <asp:BoundField DataField="uploaderName" HeaderText="Uploader" SortExpression="uploaderName" />
                <asp:BoundField DataField="uploadDate" HeaderText="Date" SortExpression="uploadDate" />
                <asp:BoundField DataField="isDeleted" HeaderText="isDeleted" SortExpression="isDeleted" Visible="False" />
            </Columns>
        </asp:GridView>
        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
            OldValuesParameterFormatString="original_{0}" SelectMethod="GetDataByUploader"
            TypeName="SecureWebTableAdapters.tblFilesTableAdapter" OnSelecting="ObjectDataSource1_Selecting" UpdateMethod="SoftDelete" DeleteMethod="Delete" InsertMethod="Insert">
            <SelectParameters>
                <asp:Parameter DefaultValue="" Name="uploaderName" Type="String" />
            </SelectParameters>
            <UpdateParameters>
                <asp:Parameter Name="isDeleted" Type="Boolean" />
                <asp:Parameter Name="id" Type="Int64" />
            </UpdateParameters>
        </asp:ObjectDataSource>
    </asp:Content>

     

     And here's the codebehind:

     
        protected void ObjectDataSource1_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
        {
            e.InputParameters["uploaderName"] = User.Identity.Name;
        }
        protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            int index = Convert.ToInt32(e.CommandArgument);
           
            if (e.CommandName == "SoftDelete")
            {
                tblFilesTableAdapter fileDBAdapter = new tblFilesTableAdapter();
                fileDBAdapter.SoftDelete(true, Convert.ToInt64(GridView1.DataKeys[index].Value));
                GridView1.DataBind();
            }
        }
        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                LinkButton l = (LinkButton)e.Row.FindControl("LinkButton1");
                l.Attributes.Add("onclick", "javascript:return " +
                "confirm('Are you sure you want to delete " +
                DataBinder.Eval(e.Row.DataItem, "fileName") + "?')");
            }
        }

        protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            tblFilesTableAdapter fileDBAdapter = new tblFilesTableAdapter();
            fileDBAdapter.SoftDelete(true, Convert.ToInt64(GridView1.DataKeys[e.RowIndex].Value));
            GridView1.DataBind();
        }

     

     

    The RowCommand function will work just fine, but RowDeleting does not....I'm a bit confused.
     

    <asp:Content id="<span" class="st"><asp:GridView id="<span" class="st"><Columns><asp:TemplateField headertext="<span" class="st"><asp:ButtonField showheader="<span" class="st"><asp:HyperLinkField headertext="<span" class="st"><asp:BoundField datafield="<span" class="st"><asp:BoundField datafield="<span" class="st"><asp:ObjectDataSource id="<span" class="st"><SelectParameters><UpdateParameters><asp:Parameter name="<span" class="st"><asp:Parameter name="<span" class="st">
            </asp:Parameter>
        </asp:Parameter>
    </UpdateParameters></SelectParameters></asp:ObjectDataSource></asp:BoundField></asp:BoundField></asp:HyperLinkField></asp:ButtonField></asp:TemplateField></Columns></asp:GridView></asp:Content>
     
    Thursday, August 23, 2007 10:37 AM

Answers

All replies

  • User-1091210821 posted

    You could modify your code like so,...only adding modified bits

    instead of this

    <%-- this one function works, but javascript doesnt --%>
                <asp:ButtonField ShowHeader="True" Text="Delete" CommandName="SoftDelete"  />

    use this

    <asp:TemplateField HeaderText="Delete">
                    <ItemTemplate>
                        <asp:Button  CommandName="SoftDelete" runat="server" Text="Delete" id="btn"/>
                    </ItemTemplate>
                </asp:TemplateField>

    and then in the code behind

    do this

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                HtmlInputButton Button b = (HtmlInputButton)e.Row.FindControl("btn");
                l.Attributes.Add("onclick", "javascript:return " +
                "confirm('Are you sure you want to delete " +
                        }
        }

    hope that helps

    Thursday, August 23, 2007 10:55 AM
  • User121806066 posted

    Thanks, but I'm more interested in getting the buttonfield working than the linkbutton. the linkbutton works fine with the javascript, its my deleting function that doesn't work with it. for some reason the buttonfield properly passes the current row index of the gridview properly, but the linkbutton does not. Even when I specify CommandArgument='<%# Eval("id") %>' for the linkbutton, its pulling the id field rather than the row index.

     So I can either fix this by passing the row index as the commandagrument for the linkbutton OR finding a way to attach to the linkbutton generated by buttonfield.
     

    Thursday, August 23, 2007 11:03 AM
  • User-1091210821 posted

    I have suggested a button in the code above, I dont know about your delete javascript though...I saw the confirm one..

    Thursday, August 23, 2007 11:05 AM
  • User121806066 posted

    I see you suggested a button, but I've already tried what you've suggested with a LinkButton. Hence why I say, I have two options here...anyone who can help with either scenario would be greatly appreciated.
     

    Thursday, August 23, 2007 11:15 AM
  • User-1091210821 posted

    Yes I am aware of that but I suggested you a button and therefore created a column like in the above code where in you can fit in your javascript as I suggested. Thats why I suggested the mod.

    Thursday, August 23, 2007 11:19 AM
  • User121806066 posted

    I don't see how using a button versus a linkbutton makes any difference in this situation.

    Furthermore, it still doesn't resolve the issue. Button, LinkButton, whatever you want to use...it's not correctly passing the row index with the commandargument.

     

    Edit: I tried making the changes from a linkbutton to a regular button, as you suggested, and it creates the same problem as I suspected. Just wanted to make sure I wasn't crazy.
     

    Maybe I need to make myself more clear. I need to know how to change the command argument to pass along the gridview current row/index.

     OR

     I need to know how to do a findcontrol on an asp:buttonfield inside a gridview. Since the buttonfield doesn't have an ID, I can't figure out how to attach to it if there is even a way.
     

    Thursday, August 23, 2007 11:21 AM
  • User-1091210821 posted

    Sorry it seems I have misunderstood your question, however

    I was suggesting that you use <asp:button rather then button field because <asp:button has an id, otherwise you will have to do some looping to get individual controls.

    The thing i suggested earlier was to add javascript on the button rather then buttonfield. The other thing is you have same command on buttonfield and linkbutton.

    Please let me know if I am still not getting the point

    Many thanks

    Thursday, August 23, 2007 11:30 AM
  • User121806066 posted

    Yes, I know they are both doing the same thing...this is because I'm trying to get either of them to work.

    Here's a synopsis again: I am trying to achieve one thing here, in one of two ways.

     
    Method 1) Use a linkbutton in a templatefield. I need to know how to pass the current selected row via the commandargument.

    Method 2) Use a buttonfield. I need to know how to attach the javascript to the field in the code behind.

    Currently I have both methods in place because neither are working, so I've been debugging both. The javascript works fine on the linkbutton, but doesn't know how to access the current row. Conversely, method 2 can modify the current row just fine, but I cannot attach a confirmation via javascript.

     
    Does this make more sense yet?
     

    Thursday, August 23, 2007 11:34 AM
  • User-1091210821 posted

    to pass the curent selected row

            '
            Dim gridRow As GridViewRow
            Dim strID, strName As String
            '
            gridRow = CType(sender, Button).Parent.Parent
            strID = gridRow.Cells(0).Text                     //item in the first row
            strName = gridRow.Cells(1).Text              // item in the second row

     

    or

    protected Sub GridView_RowCommand(object sender, GridViewCommandEventArgs e)

                'find out which row was clicked
                Dim rowIndex as Int = e.CommandArgument;

                dim DBID as Int = sender.DataKeys(rowIndex).Value;

    End Sub

    or in c#
    protected void CategoryDataGrid_RowCommand(object sender, GridViewCommandEventArgs e)
          {
                // find out which row was clicked
                int rowIndex = Utilities.CommonFunctions.ConvertToInt(e.CommandArgument);

                String DBID = Utilities.CommonFunctions.ConvertToString(((GridView)sender).DataKeys[rowIndex].Value);
          }

    for adding confirm on button field

    It can be done by adding an OnClickClient property to the ButtonField class. Here is how such an inherited class would look like

     public class MyButtonField : ButtonField

    {

            #region Properties [DefaultValue(""),

            Themeable(false)] public virtual string OnClientClick

            { get { string text = (string)

                this.ViewState["OnClientClick"];

                    if (text == null) return string.Empty;

                       return text;

            }

              set { this.ViewState["OnClientClick"] = value; } }

                #endregion Properties

          public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)

              {

                                 base.InitializeCell(cell, cellType, rowState, rowIndex);

                               if (cell.Controls.Count > 0)

                                  { Control control; control = cell.Controls[0];

                                          if (control is Button) { ((Button)control).OnClientClick = OnClientClick; }

                                            else if (control is LinkButton) { ((LinkButton)control).OnClientClick = OnClientClick; }

                                              else if (control is ImageButton) { ((ImageButton)control).OnClientClick = OnClientClick; } } }

                            protected override void CopyProperties(DataControlField newField)

                             { ((MyButtonField)newField).OnClientClick = this.OnClientClick; base.CopyProperties(newField); }

                         protected override DataControlField CreateField() { return new MyButtonField(); } }    

    now you can just use onclientclick property.   

    Thursday, August 23, 2007 12:04 PM
  • User121806066 posted

      Rewriting the class is definitely an option I hadn't thought of. I'll look into that a bit more, but not a bad suggestion.

     I like the first solution a bit better..the only problem is, I'm still not getting the rowindex because e.commandargument is null. I need to actually pass the rowindex, and that is what I"m having trouble figuring out. How do I assign the current row index to the command argument?
    Thursday, August 23, 2007 12:26 PM
  • User-1091210821 posted

    Its going to work for a button not a linkbutton

    check here

    http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowcommand.aspx

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 23, 2007 12:30 PM
  • User121806066 posted

    That link was exactly what I needed! Thank you!

    What I had to do was add this event:

        protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                LinkButton deleteButton = (LinkButton)e.Row.Cells[0].Controls[0];
                deleteButton.CommandArgument = e.Row.RowIndex.ToString();
                deleteButton.OnClientClick = "javascript:return confirm('Are you sure you want to delete " +
                DataBinder.Eval(e.Row.DataItem, "fileName") + "?')";
            }
        }
     

    And now my buttonfield works perfectly!!! Thanks for your help my man! I appreciate your patience and help!
     

    Thursday, August 23, 2007 1:04 PM
  • User-359330906 posted

    I have similar type of issue , can you please let me know how exactly your javascript works !!

    I have

    <asp:buttonfield buttontype="Image" ImageUrl="~/Images/edit.gif" commandname="EditLinkClicked"/>

    <asp:ButtonField ButtonType ="Image" ImageUrl ="~/Images/Delete.gif" CommandName="DeleteLinkClicked" CausesValidation="false" />

    and then

    protected void gvLinkPage_RowCreated(Object sender, GridViewRowEventArgs e)

    {

    if (e.Row.RowType == DataControlRowType.DataRow)

    {

    // Retrieve the LinkButton control from the first column.

    ImageButton deleteButton = (ImageButton)e.Row.Cells[11].Controls[0];

    // Set the LinkButton's CommandArgument property with the

    // row's index.

    //deleteButton.CommandArgument = e.Row.RowIndex.ToString();

    deleteButton.OnClientClick = "javascript:return confirm('Are you sure you want to delete.')";

    }

    }

    protected void gvLinkPage_RowCommand(object sender, GridViewCommandEventArgs e)

    {

    case "DeleteLinkClicked":

     

    AddCategory1.Visible =
    false;

    EditLinkPage1.ClearMessages();

    index =
    Convert.ToInt32(e.CommandArgument);

    row = gvLinkPage.Rows[index];

    //.....................some code which is not important here to show

    }

    }

    The problem is when i click the delete iamge in the grid i get the the javaecript alert box, but when I click "OK" to the alert it doesnot excute the "DeleteLinkClicked" in 

    protected void gvLinkPage_RowCommand(object sender, GridViewCommandEventArgs e)

    so actually the record is still exist and it not been deleted.

    Is there any problem with my javascript??

    Please let me know.It will be a great help.

     

    Wednesday, May 14, 2008 3:52 PM