views:

569

answers:

5

I need to capture the 'Update' click event with jQuery in an asp.net GridView and have no way of knowing where to start. I'm still rather new to jQuery. My GridView is attached to a SQLDataSource and, naturally, has all the bells and whistles that that combination affords. Any help would be greatly appreciated.

A: 

You need to attach a client-side event listener to the click event of the Update [link]button. I don't think it can be done using AutoGenerateEditButton="true" if you are doing it that way. You'll need to use a TemplateField so that you can manipulate the button. Then you can use jQuery to bind to the click event of the button.

rchern
A: 

Add the update column to the column templates. Convert it to a custom column, and modify it in such a way you can hook to it with jquery i.e. like adding a css class to it.

eglasius
+2  A: 

Ok here is my solution to capture only one update (or more) from a button.

This is the javascript code that I run on update click

<script type="text/javascript">         
  function NowRunTheUpdate(){
      alert("ok I capture you");
  } 
</script>

and here is the page code

    `<asp:GridView ID="MyGridView" runat="server" OnRowDataBound="MyGridView_RowDataBound" ... >`

    <asp:ButtonField Text="update" CommandName="Update" ButtonType="Button" />  
  ...

Here is the code thats run behind and set the javascript.

protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        // loop all data rows
        foreach (DataControlFieldCell cell in e.Row.Cells)
        {
            // check all cells in one row
            foreach (Control control in cell.Controls)
            {
                // I go to get the button if exist
                Button button = control as Button;
                if (button != null && button.CommandName == "Update")
                    // Add delete confirmation
                    button.OnClientClick = "NowRunTheUpdate();";
            }
        }
    }
}
Aristos
+6  A: 

Simply add the script block anywhere after the GridView is declared and it should work with the default non-templated GridView column. No code in the codebehind as it is purely a Javascript solution.

Use this if you are using a Link-type GridView column:

<script type="text/javascript">
    // a:contains(The text of the link here)
    $('#<%= theGridViewID.ClientID %> a:contains(Update)').click(function () {
        alert('Update click event captured from the link!');
        // return false: stop the postback from happening
        // return true or don't return anything: continue with the postback
    });
</script>

Use this if you are using a Button-type GridView column and you don't want your Javascript to block the postback:

<script type="text/javascript">
    // :button[value=The text of the button here]
    $('#<%= theGridViewID.ClientID %> :button[value=Update]').click(function () {
        alert('Update click event captured from the button!');
    });
</script>

Use this if you are using a Button-type GridView column and you want to have control whether to continue with the postback or not:

<script type="text/javascript">
    // :button[value=The text of the button here]
    var updateButtons = $('#<%= theGridViewID.ClientID %> :button[value=Update]');
    updateButtons
        .attr('onclick', null)
        .click(function () {
            alert('Update click event captured from the button!');
            var doPostBack = true; // decide whether to do postback or not
            if (doPostBack) {
                var index = updateButtons.index($(this));
                // 'Update$' refers to the GridView command name + dollar sign
                __doPostBack('<%= theGridViewID.UniqueID %>', 'Update$' + index);
            }
        });
</script>

Update: I think this would be a better solution in replacement of the last (3rd) script block I presented above, since you won't need to update the __doPostBack function call manually based on the command name, and as such, it should be less error-prone:

<script type="text/javascript">
    // :button[value=The text of the button here]
    var updateButtons = $('#<%= theGridViewID.ClientID %> :button[value=Update]');
    updateButtons.each(function () {
        var onclick = $(this).attr('onclick');
        $(this).attr('onclick', null).click(function () {
            alert('Update click event captured from the button!');
            var doPostBack = true; // decide whether to do postback or not
            if (doPostBack) {
                onclick();
            }
        });
    });
</script>

Credit to Aristos for this idea. :)

Amry
I said the script block should be put somewhere after the GridView is declared, but if for whatever reason you insist it to appear somewhere before (in the head section perhaps?), you can always wrap the script with $(function() { /* scripts in here */ }) so that the script will only be executed only after the DOM is ready.
Amry
@Amry nice work I like yours too. My only fair is that you actually try to recreate the doPostBack - is there any way to get what actually exist on control in OnClick event, before change it, save it in a function variable, and call it after his work.
Aristos
@Aristos: Good suggestion indeed. Strange I somehow never thought of that. Updated my answer to include this, credit to you. :)
Amry
@Amry very good - I prefer your solution a little more than the one I have post.
Aristos
A: 

Gridview is nothing but a table with a bunch of "tr" and "td". If you understand that concept then it would be easy for you to handle anything at client side. If you have enabled auto everything then it will be a link which would result for Edit, Delete, Update or Cancel (Check View Source). The code given below should capture the update click event:

    $("a:contains(Update)").live("click", function() { 
   //alert("hi"); do what needs to be done
    return false;//would not sent the control back to server 
    });

HTH

Raja
@Raja I like this idea - its need some work in case that you have many grids, and be sure not to conflict with other update buttons but I like it. Also you need jQuery but I use it anyway. And the better part from my idea is that you do not need to loop the grid on code-behind. I will try to test it and maybe use it.
Aristos
@Raja I check just now the code and I think its need something more - if you can help on that. This is not link but input, and then the input make the postBack onClick. How you can capture and save the postBack that all ready exist inside the input (using jQuery?
Aristos
@Raja <input type="button" value="UpdateMe" onclick="javascript:__doPostBack('ctl00$MyGridName','UpdateMe$1')" /> here is the code that you need to insert your OnLick. Can you help ?
Aristos
@Aristos : Sorry for the late reply. instead of using $("a:contains(Update)") try this: $("input[value='UpdateMe']")HTH
Raja
@Raja this way you lose the __doPostBack function... is there a way to capture it, do what you won and then run the doPostBack ?
Aristos
@Aristos: Just comment the return false; and it should do a postback. HTH
Raja