How can I correctly capture and re-fire the form submit event, guaranteed?

前端 未结 4 1054
名媛妹妹
名媛妹妹 2021-02-07 03:23

This is probably not your usual \"How do I capture form submit events?\" question.

I\'m trying to understand precisely how form submit events are handled by jQu

4条回答
  •  礼貌的吻别
    2021-02-07 03:32

    There must be many ways to address this - here's one.

    It keeps your ajax function (A) separate from all the others (B, C, D etc.), by placing only A in the standard "submit" queue and B, C, D etc. in a custom event queue. This avoids tricky machinations that are otherwise necessary to make B, C, D etc. dependent on A's asynchronous response.

    $(function(){
        var formSubmitQueue = 'formSubmitQueue';
    
        //Here's a worker function that performs the ajax.
        //It's coded like this to reduce bulk in the main supervisor Handler A.
        //Make sure to return the jqXHR object that's returned by $.ajax().
        function myAjaxHandler() {
            return $.ajax({
                //various ajax options here
                success: function(data, textStatus, jqXHR) {
                    //do whatever is necessary with the response here
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    //do whatever is necessary on ajax error here
                }
            });
        }
    
        //Now build a queue of other functions to be executed on ajax success.
        //These are just dummy functions involving a confirm(), which allows us to reject the master deferred passed into these handlers as a formal variable.
        $("#myForm").on(formSubmitQueue, function(e, def) {
            if(def.state() !== 'rejected') {
                if (!confirm('Handler B')) {
                    def.reject();
                }
            }
        }).on(formSubmitQueue, function(e, def) {
            if(def.state() !== 'rejected') {
                if (!confirm('Handler C')) {
                    def.reject();
                }
            }
        }).on(formSubmitQueue, function(e, def) {
            if(def.state() !== 'rejected') {
                if (!confirm('Handler D')) {
                    def.reject();
                }
            }
        });
    
        $("#myForm").on('submit', function(e) {
            var $form = $(this);
            e.preventDefault();
            alert('Handler A');
            myAjaxHandler().done(function() {
                //alert('ajax success');
                var def = $.Deferred().done(function() {
                    $form.get(0).submit();
                }).fail(function() {
                    alert('A handler in the custom queue suppressed form submission');
                });
                //add extra custom handler to resolve the Deferred.
                $form.off(formSubmitQueue+'.last').on(formSubmitQueue+'.last', function(e, def) {
                    def.resolve();
                });
                $form.trigger(formSubmitQueue, def);
            }).fail(function() {
                //alert('ajax failed');
            });
        });
    });
    

    DEMO (with simulated ajax)

    As an added bonus, any of the handlers in the custom queue can be made to suppress any/all following handlers, and/or suppress form submission. Just choose the appropriate pattern depending on what's required :

    Pattern 1:

    Performs its actions only if all preceding handlers have not rejected def. and can suppress all following handlers of Pattern 1 and Pattern 2.

    $("#myForm").on(formSubmitQueue, function(e, def) {
        if(def.state() !== 'rejected') {
            //actions as required here
            if (expression) {
                def.reject();
            }
        }
    });
    

    Pattern 2:

    Performs its actions only if all preceding handlers have not rejected def. but does not suppress following handlers.

    $("#myForm").on(formSubmitQueue, function(e, def) {
        if(def.state() !== 'rejected') {
            //actions as required here
        }
    });
    

    Pattern 3:

    Performs its actions unconditionally but can still suppresses all following handlers of Pattern 1 and Pattern 2.

    $("#myForm").on(formSubmitQueue, function(e, def) {
        //actions as required here
        if (expression) {
            def.reject();
        }
    });
    

    Pattern 4:

    Performs its actions unconditionally, and does not suppress following handlers.

    $("#myForm").on(formSubmitQueue, function(e, def) {
        //actions as required here
    });
    

    Notes:

    • The deferred could be resolved in these handlers in order to submit the form immediately without processing the rest of the queue. But in general, the deferred will be resolved by the '.last' handler added to the queue dynamically before the queue is triggered (back in Handler A).
    • In the Demo, all the handlers are of Pattern 1.

提交回复
热议问题