javascriptjqueryajaxsynchronoussmart-wizard

Show waiting dialog on synchronous ajax


I want to show a waiting dialog while a synchronous ajax is made. I using a Smart Wizard, to change between step one to step to i have to validate some data to do that i have to make 3 ajax call one after the other and while this is done i want to show a waiting dialog. This is what I'm doing.

if (indexes.fromStep==1) {  
    res=false;  
    var validatorResult = validator.checkAll($("#install_modbus_form"))
    if (validatorResult) {          
        $("#modal_loader").modal()      
        $.ajax({
            type: "post",
            url: url1, 
            async: false,            
            dataType: "json",   
            data:{
                data
            },     
            success: function(response)
            { 
                if (response.success) 
                {
                    $.ajax({
                        type: "post",
                        url: url2, 
                        async: false,            
                        dataType: "json",   
                        data:{
                            data
                        },     
                        success: function(response)
                        { 
                            if (response.success) 
                            {
                                $.ajax({
                                    type: "post",
                                    url: url3, 
                                    async: false,            
                                    dataType: "json",   
                                    data:{
                                        data
                                    },     
                                    success: function(response)
                                    { 
                                        if (response.success) 
                                        {
                                            //make magic here
                                            res=true;
                                        }
                                    },
                                    failure:function() 
                                    {
                                        waitingDialog.hide()
                                        res=false
                                    },
                                    error:function(a,b,c) {
                                        waitingDialog.hide()
                                        res=false
                                    }
                                )
                            }
                        },
                        failure:function() 
                        {
                            waitingDialog.hide()
                            res=false
                        },
                        error:function(a,b,c) {
                            waitingDialog.hide()
                            res=false
                        }
                    )
                }
            },
            failure:function() 
            {
                waitingDialog.hide()
                res=false
            },
            error:function(a,b,c) {
                waitingDialog.hide()
                res=false
            }
        )
        $("#modal_loader").modal('hide')        
        return res;//if true change step 
    }
}

I have trie use beforeSend to show the waiting dialog, also i have trie to use setTimeout but the waiting dialog is not show and the smart wizard dont go forward

Hope you can help, Im new in jquery.

Sorry for the bad english


Solution

  • On the assumption that you are using jQuery-Smart-Wizard, the solution lies in :

    Fortunately, even though the plugin does not natively support asynchronism, it is fairly simple to make it do so. Essentially, what you need to do is :

    Based on smartWizard's ReadMe.md, here's a framework for performing synchronous and asynchronous validations :

    $(document).ready(function() {
        var waitingDialog = $('#whatever'); // ???
    
        // Smart Wizard         
        $('#wizard').smartWizard({
            onLeaveStep: leaveAStepCallback,
            onFinish: onFinishCallback
        });
    
        function leaveAStepCallback(obj, context) {
            alert("Leaving step " + context.fromStep + " to go to step " + context.toStep);
            var returnValue;
            switch(context.fromStep) {
                case 1: // asynchronous
                    if (validator.checkAll($("#install_modbus_form"))) {
                        $("#modal_loader").modal();
                        waitingDialog.show();
                        validateStep1() // validateStep1() returns a promise
                        .then(function() {
                            // You will arrive here only if all three ajax calls were successful and all three responded with a truthy `response.success`.
                            $('#wizard').smartWizard('goForward'); // advance to next step
                        }, function(e) {
                            // You will arrive here on validation failure
                            $('#wizard').smartWizard('showError', e.message); // something went wrong
                        }).always(function() {
                            // You will arrive here on validation success or failure
                            waitingDialog.hide(); // the waiting is over
                            $("#modal_loader").modal('hide'); // ???
                        });
                    } else {
                        $('#wizard').smartWizard('showError', 'validator.checkAll() failed');
                    }
                    returnValue = false; // *must* return false to remain at step 1. If validation is successful, `.smartWizard('goForward')` will be executed later (see above).
                break;
                case 2: // synchronous
                    returnValue = validateStep2(); // validateStep2() returns true of false
                break;
                case 3:
                    ...
                break;
            }
            return returnValue; // true or false
        }
    
        // And here's the all-important `validateStep1()` :
        function validateStep1() {
            var sequence = [
                { url: 'url/1', data: {...} },
                { url: 'url/2', data: {...} },
                { url: 'url/3', data: {...} }
            ];
    
            return sequence.reduce(function(promise, item, i) {
                return promise.then(function() {
                    return $.ajax({
                        'type': 'post',
                        'url': item.url,
                        'dataType': 'json',
                        'data': item.data
                    }).then(function(response, textStatus, jqXHR) {
                        return response.success ? response : $.Deferred().reject(jqXHR, 'response.success not truthy at validation stage ' + i); // note: need to mimic jQuery.ajax's error signature.
                    });
                });
            }, $.when()) // starter promise for the reduction
            .then(null, function(jqXHR, textStatus, errorThrown) {
                return $.Deferred().reject(new Error(textStatus || errorThrown));
            });
        }
    
        function validateStep2() {
            // if validation here is synchronous, then return true of false
            if(....) {
                return true;
            } else {
                return false;
            }
        }
        function validateStep3() {
            ...
        }
        // etc.
    
        function onFinishCallback(objs, context) {
            if(validateAllSteps()) {
                $('form').submit();
            }
        }
    
        function validateAllSteps() {
            var isStepValid = true;
            // all step validation logic     
            return isStepValid;
        }          
    });
    

    Notes :

    As you can see, some aspects above are incomplete so there's still some work to do.