34

I'm trying to handle the submit event of a form element using jQuery.

    $("form").bind("submit", function() {
        alert("You are submitting!");
    });

This never fires when the form submits (as part of a postback, e.g. when I click on a button or linkbutton).

Is there a way to make this work? I could attach to events of the individual elements that trigger the submission, but that's less than ideal - there are just too many possibilities (e.g. dropdownlists with autopostback=true, keyboard shortcuts, etc.)


Update: Here's a minimal test case - this is the entire contents of my aspx page:

<%@ page language="vb" autoeventwireup="false" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:scriptmanager id="ScriptManager" runat="server" enablepartialrendering="true">
                <scripts>
                    <asp:scriptreference path="/Standard/Core/Javascript/Jquery.min.js" />
                </scripts>
            </asp:scriptmanager>
            <p>
                <asp:linkbutton id="TestButton" text="Click me!" runat="server" /></p>
        </div>
    </form>

    <script type="text/javascript">
        $(document).ready(function() {
            alert("Document ready.");
            $("form").submit(function() {
                alert("Submit detected.");
            });
        });
    </script>

</body>
</html>

I get the "Document ready" alert, but not the "Submit detected" when clicking on the linkbutton.

Herb Caudill
  • 50,043
  • 39
  • 124
  • 173

8 Answers8

39

Thanks, @Ken Browning and @russau for pointing me in the direction of hijacking __doPostBack. I've seen a couple of different approaches to this:

  1. Hard-code my own version of __doPostBack, and put it later on the page so that it overwrites the standard one.
  2. Overload Render on the page and inject my own custom code into the existing __doPostBack.
  3. Take advantage of Javascript's functional nature and create a hook for adding functionality to __doPostBack.

The first two seem undesirable for a couple of reasons (for example, suppose in the future someone else needs to add their own functionality to __doPostBack) so I've gone with #3.

This addToPostBack function is a variation of a common pre-jQuery technique I used to use to add functions to window.onload, and it works well:

addToPostBack = function(func) {
    var old__doPostBack = __doPostBack;
    if (typeof __doPostBack != 'function') {
        __doPostBack = func;
    } else {
        __doPostBack = function(t, a) {
            if (func(t, a)) old__doPostBack(t, a);
        }
    }
};

$(document).ready(function() {
    alert("Document ready.");
    addToPostBack(function(t,a) {
        return confirm("Really?")
    });
});

Edit: Changed addToPostBack so that

  1. It can take the same arguments as __doPostBack.
  2. The function being added takes place before __doPostBack.
  3. The function being added can return false to abort postback.
Michael
  • 8,362
  • 6
  • 61
  • 88
Herb Caudill
  • 50,043
  • 39
  • 124
  • 173
  • great solution to show a loading notification with jQuery while using AutoPostBack for controls in update panels. – Bobby Borszich Feb 08 '11 at 16:44
  • 1
    Thank you very much for this answer! I was having a really hard time with this in Sharepoint, but couldn't figure out why. I thought I would leave a comment in case anyone else was sttruggling with this. For Sharepoint, in addition to your code, you need to add the following right before your anonymous function returns: _spFormOnSubmitCalled = false; – electrichead Aug 26 '11 at 21:06
  • Great thanks for sharing this. I was just having the opposite problem - a jQuery handler for the form's submit event was being fired (and showing a loading gif) but _doPostBack wasn't being called because validation failed. Very strange, but no longer a problem! – tomfumb Dec 03 '11 at 21:09
  • 1
    I took this solution and put it in a jQuery plugin: http://plugins.jquery.com/beforePostBack/ – Peter Mar 21 '13 at 08:02
15

I've had success with a solution with overriding __doPostBack() so as to call an override on form.submit() (i.e. $('form:first').submit(myHandler)), but I think it's over-engineered. As of ASP.NET 2.0, the most simple workaround is to:

  1. Define a javascript function that you want to run when the form is submitted i.e.

    <script type="text/javascript">
    
    function myhandler()
    {
        alert('you submitted!');
    }
    
    </script>
    
  2. Register your handler function within your codebehind i.e.

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        ScriptManager.RegisterOnSubmitStatement(Page, Page.GetType(), 
                                                "myHandlerKey", "myhandler()");
    }
    

That's all! myhandler() will be called from straightforward button-input submits and automatic __doPostBack() calls alike.

Michael
  • 8,362
  • 6
  • 61
  • 88
James McCormack
  • 9,217
  • 3
  • 47
  • 57
  • Just to clarify, in your example "myHandlerKey" is the id of the form tag. Like this:
    – whitneyland Nov 23 '11 at 21:30
  • Sorry, no - check the documentation: http://msdn.microsoft.com/en-us/library/bb301794.aspx. The *key* uniquely identifies the script to help prevent duplicate registration. Incidentally there should be no need to uniquely identify a form element as webforms only allow one form per page. – James McCormack Nov 24 '11 at 09:42
  • To clarify: webforms only allow one form per page declared with *runat="server"*. You may have other non-server forms on the page. – James McCormack Nov 24 '11 at 09:57
  • I like this. It's the proper ".NET way" of handling things. – m-albert Feb 27 '15 at 20:59
4

Yeah, this is annoying. I replace __doPostBack with my own so that I could get submit events to fire.

Iirc, this is an issue when submitting a form via javascript (which calls to __doPostBack do) in IE (maybe other browsers too).

My __doPostBack replacement calls $(theForm).submit() after replicating the default behavior (stuffing values in hidden inputs)

Ken Browning
  • 28,693
  • 6
  • 56
  • 68
  • 2
    Hijacking __doPostBack : http://weblogs.asp.net/vga/archive/2004/03/01/NoMoreHijackingOfDoPostBackInWhidbey.aspx – russau Aug 05 '09 at 00:25
  • @russau - It's my impression from the article that postback hijacking shouldn't be necessary as of Whidbey (VS2005)? – Herb Caudill Aug 05 '09 at 14:02
  • 2
    @Herb Well, their cause for hijacking is different than yours. It sounds like their cause has been addressed. Yours definitely has not. If you want jQuery submit events to be fired whenever a postback is initiated by a call to __doPostBack then you'll need to hijack __doPostBack. – Ken Browning Aug 05 '09 at 15:36
1

I don't know how to do it with jQuery, but you could add an OnClientClick property to the ASP.NET control:

<asp:linkbutton id="TestButton" text="Click me!" runat="server" OnClientClick="alert('Submit detected.');" />
Powerlord
  • 87,612
  • 17
  • 125
  • 175
  • This doesn't help in my situation. First, if I was going to handle every single control that might trigger a postback, it would be a better solution to use jQuery to capture events on these across the board. But what I need is a global solution on lots of different forms, and I don't want to go back and touch every single control that could possible trigger a postback. – Herb Caudill Aug 05 '09 at 17:47
1

If you are using .NET Framework 3.5 or up, you can use ScriptManager.RegisterOnSubmitStatement() in your server-side code. The registered script will get called both on normal submit and on DoPostback.

ScriptManager.RegisterOnSubmitStatement(this, this.GetType(), "myKey", "SomeClientSideFunction();");
fripp13
  • 160
  • 2
  • 5
0

This works for capturing the submit:

$("form input[type=submit]").live("click", function(ev) {
    ev.preventDefault();
    console.log("Form submittion triggered");
  });
Freeman
  • 5,810
  • 3
  • 47
  • 48
0
 $(document).ready(function () {

          $(this).live("submit", function () {

                console.log("submitted");
             }
}
zamoldar
  • 548
  • 10
  • 13
-2

You need to add OnclientClick to linkbutton

OnClientClick="if(!$('#form1').valid()) return false;"

Gray
  • 7,050
  • 2
  • 29
  • 52
Phanindra Kumar
  • 171
  • 3
  • 16