A: 

Well you could do something like:

function beforeSubmit() {
    if (isValid($(this)) {
      $.ajax({
          type: 'POST',
          url: '/form/submit',
          success: afterSubmit
      });
    }
    return false;
}

function afterSubmit() {
}
reko_t
If you never care about an error in the request, you can alternatively just use $.get or $.post, the callback for those will be called after the response is returned.
reko_t
As I say, you can't fix logic for submit event. Because I don't sure how many function in before submit or after submit.
Soul_Master
A: 

Your best bet is not to do this as a "normal" submission at all but use a method of Ajax submission. There are several of these. Check out Form Submission ajaxSubmit().

Assuming you make another Ajax call to validate the form somehow (or, say, retrieve additional information from another site) you could follow this process:

  1. User clicks "submit";
  2. Disable the submit button;
  3. Make an Ajax call to validate, retrieve extra information or whatever;
  4. In the callback for the completion of this Ajax call, call ajax submit;
  5. When that submit returns send the user to a new page or do whatever.
cletus
Please look at my updated question.
Soul_Master
A: 

I just solve my question with event wrapper by using the following code. It's quite long code. But it works well on my basic testing. I can assign prepare submit event for watermark extender, before submit event for control validator, submit event for sending form data via AJAX and after submit event for form posting indicator.

/* jQuery - Form Submit Event Extender */
var _prepareSubmitFunction = new Object();
var _beforeSubmitFunction = new Object();
var _submitFunction = new Object();
var _afterSubmitFunction = new Object();
jQuery.fn._oldSubmit = jQuery.fn.submit;

function formSubmitEventExtender_Init(form)
{
    form = $(form);

    form.unbind('submit.formSubmitEventExtender');
    form.bind('submit.formSubmitEventExtender', null, function ()
    {
        form.prepareSubmit();

        if (form.beforeSubmit())
        {
            var result = true;

            for (var i in _submitFunction[form.attr('id')])
            {
                var temp = _submitFunction[form.attr('id')][i]();
                temp = ((temp === false) ? false : true);

                result = result && temp;
            }

            form.afterSubmit();

            return result;
        }
        else
        {
            return false;
        }
    });
}

jQuery.fn.prepareSubmit = function (fn)
{
    var x = $(this);
    x.ensureHasId();
    var id = x.attr('id');

    if (fn)
    {
        if (!_prepareSubmitFunction[id])
        {
            _prepareSubmitFunction[id] = new Array();
            formSubmitEventExtender_Init(x);
        }

        if ($.inArray(fn, _prepareSubmitFunction[id]) < 0)
            _prepareSubmitFunction[id].push(fn);
    }
    else
    {
        for (var i in _prepareSubmitFunction[id])
        {
            _prepareSubmitFunction[id][i]();
        }
    }

    return x;
};
jQuery.fn.beforeSubmit = function (fn)
{
    var x = $(this);
    x.ensureHasId();
    var id = x.attr('id');

    if (fn)
    {
        if (!_beforeSubmitFunction[id])
        {
            _beforeSubmitFunction[id] = new Array();
            formSubmitEventExtender_Init(x);
        }

        if ($.inArray(fn, _beforeSubmitFunction[id]) < 0)
            _beforeSubmitFunction[id].push(fn);
    }
    else
    {
        for (var i in _beforeSubmitFunction[id])
        {
            if (!_beforeSubmitFunction[id][i]())
                return false;
        }

        return true;
    }

    return x;
};
jQuery.fn.submit = function (fn)
{
    var x = $(this);
    x.ensureHasId();
    var id = x.attr('id');

    if (fn)
    {
        if (!_submitFunction[id])
        {
            _submitFunction[id] = new Array();
            formSubmitEventExtender_Init(x);
        }

        if ($.inArray(fn, _submitFunction[id]) < 0)
            _submitFunction[id].push(fn);
    }
    else
    {
        x._oldSubmit();
    }

    return x;
};
jQuery.fn.afterSubmit = function (fn)
{
    var x = $(this);
    x.ensureHasId();
    var id = x.attr('id');

    if (fn)
    {
        if (!_afterSubmitFunction[id])
        {
            _afterSubmitFunction[id] = new Array();
            formSubmitEventExtender_Init(x);
        }

        if ($.inArray(fn, _afterSubmitFunction[id]) < 0)
            _afterSubmitFunction[id].push(fn);
    }
    else
    {
        for (var i in _afterSubmitFunction[id])
        {
            _afterSubmitFunction[id][i]();
        }
    }

    return x;
};
Soul_Master