views:

1124

answers:

2

I'm trying to stop postback on form submit if my custom jQuery validation returns false.

Is there any way to prevent the __doPostback() function finishing from within the submit() function?

I'd assumed:

$('#aspnetForm').submit(function () { return false; });

would do the trick, but apparently that's not the case: does anyone have a suggestion?

The submit() function does block the postback (it won't postback if you pause at a breakpoint in firebug), but I can't seem to stop the event happening after the submit() function is complete!

Cheers, Ed

EDIT

OK, I had a quick mess about and discovered that the fact that the button I'm using to cause the postback is tied to an updatepanel as an asyncpostbacktrigger seems to be the problem: If I remove it as a trigger (i.e. cause it to product a full postback), the is no problem preventing the postback with return false;

Any ideas why the async postback would not be stoppable using return false?

+3  A: 
$('#yourPostButton').click(function(){  
    return false; 
});

This should do!

tucaz
@tucaz, hope you don't mind editing your answer.
rahul
Yes, but then I'd need to attach that to every button on the form, which isn't very sensible. I need to be able to do it with submit() (or some equivalent) so I can use the control that utilises the code without having to configure it on a by-the-page basis.
Ed Woodcock
If it's not a problem to you you can add it to every button with $('input[type=button]') or something like that or try the .preventDefault() as suggested by jQuery documentation here http://api.jquery.com/submit/
tucaz
Another idea would be get a reference do the original __doPostBack function and replace it with some dummy function if you want to interrupt the postback. Something like this: var __oldPostBack = __doPostBack; __doPostBack = function() { //check if you can post, then call __oldPostBack() }
tucaz
yeah, true with the selector, but in ASP.net anything can cause a postback, such as dropdownlist selectedindexchanged (one we're using a lot), so I'd have to bind various events depending on input type, which is getting a little overly complex. As for preventDefault(), return false calls this automatically anyway, as you can see if you step through a return with firebug.
Ed Woodcock
chaining __doPostBack has some issues if you try and do it more than once, which means it would get very complex when multiple controls needed to add functionality to __doPostback
Ed Woodcock
+2  A: 

You have to use the client side PageRequestManager to properly handle AJAX submit events. (e.g. prevent an async postback.)

If you are not in total control of the page, there can be JavaScript on the page that just calls __doPostBack() without going through any page logic. In this case - in addition to the above -, you have to store the old window.__doPostBack() and provide your own - as @tucaz mentioned in his comments. (...and as you mentioned, it can get quite perplexing with chaining.) For regular submits (non-AJAX), you can provide an event handler as others have pointed out.

This page might be of help and has some code samples that use PageRequestManager. In particular:

initialize : function()
{
    ...

    this._onSubmitHandler = Function.createDelegate(this, this._onSubmit);
    this._onPartialUpdateEnd = Function.createDelegate(this, this._onUpdateEnd);

    if (typeof(Sys.WebForms)!== "undefined" && typeof(Sys.WebForms.PageRequestManager)!== "undefined")
    {
        Array.add(Sys.WebForms.PageRequestManager.getInstance()._onSubmitStatements, this._onSubmitHandler);
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(this._onPartialUpdateEnd);
    }
    else 
        $addHandler(document.forms[0], "submit", this._onSubmitHandler);
},

Edit: Following the above, this, for example works fine for me (.Net 3.5 SP1, Button1 is trigger in the updatepanel, etc...):

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>

    <script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.2.js" charset="utf-8"
        type="text/javascript"></script>

</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <div>
                <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
            </div>
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="Button1" />
        </Triggers>
    </asp:UpdatePanel>
    </form>
    <script type="text/javascript">
        (function($, undefined) {

            var submitHandler = function(e) {
                return false;
            }

            if (typeof (Sys.WebForms) !== "undefined" && typeof (Sys.WebForms.PageRequestManager) !== "undefined") {
                Array.add(Sys.WebForms.PageRequestManager.getInstance()._onSubmitStatements, submitHandler);
            } else {
                $("form").submit(submitHandler);
            }
        })(jQuery);
    </script>
</body>
</html>
andras
Yes, I've been through the UpdatePanel docs and it seems that you can cancel async postbacks with PageRequestManager.getInstance().abortPostBack(). However, it seems that this is not working correctly: my submit() handler is no longer blocking the postback.
Ed Woodcock
@Ed Woodcock: By looking at the source and article found e.g. on http://msdn.microsoft.com/en-us/magazine/cc163380.aspx, abortPostBack() is for canceling a request that has been *already started*.
andras