0

Let's start from here - I have defined base setting for all future AJAX-requests, like this

$.ajaxSetup({
  beforeSend : function(){
      $("#ajax-loader").dialog({
         modal : true 
      });
  },

  complete : function(){
     $("#ajax-loader").dialog("hide");
  }
});

Now, I have a form where my users can upload their bio and pictures. When a form is valid, then I allow to upload their pictures. It works this way:

$("#send").click(function(e){
   e.preventDefault();

   $.ajax({
      data : $("#bio-form").serialize(),
      url : "/validate.ajax",
      success : function(response) {
        // If AJAX-validator returns "1" then a form is valid  
        if (response == "1"){

            // Now I start to upload photos, like
            // this

            var formData = new FormData(document.getElementById('upload-form'));

            $.ajax({
               processData  : false,
               contentType  : false,
               cache    : false,
               data         : formData,
               success : function(response) {
                  alert(response);
               }
            });
        }
      }
   });

});

The problem

Once ajax-uploading starts, I expect a $("#ajax-loader") to be showed. On complete this should be closed automatically according to the settings I defined in $.ajaxSetup.

BUT... It appears and disappears right after 1 sec on file uploading. I know that ajax request isn't completed, because I get successfuly message after 1-2 mins (that photos uploaded).

I tried to change async: false and it started to work as expected === a modal appears when uploading files to server and disappers when done:

data        : formData,
async       : false,
processData : false,

Question

Is it possble to do the same when async : true is set to its default mode(true)? I don't want a browser to be frozen when uploading in progress!

DontVoteMeDown
  • 21,122
  • 10
  • 69
  • 105

2 Answers2

0

As you've discovered, Ajax is an asynchronous technology - meaning it runs on its own schedule

Making Ajax synchronous causes all sorts of problems (using async:false actually causes the browser to freeze whilst the request is performed)

There are several issues I'd mention you may want to fix:


Why Nested Ajax?

Nesting Ajax requests, in this current state of the web, is, in my opinion, bad practice. It generally means you've got something wrong with your system. Concurrent requests are fine - but nested I'd avoid like the plague


Ajax Callbacks

If you can get your Ajax requests down to a single entity, I'd look at using Ajax Callbacks to create your desired result

Ajax callbacks work by using Ajax as part of a function, where the success & error callbacks are handled by several differnt parts of your parent function. Here's an example:

 function create_modal(o){

        fetch_modal(o.ajax, function(data){
           //do success stuff here
        }, function(data){
           //do error stuff here
        });

 }

 function fetch_modal(link, success, error) {
     $.ajax({
        url: link,
        success: function(data) { success(data); },
        error: function(data)   { error(data); }
     });
 } 
Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
0

The problem is ajaxSetup. You have to follow enable/disable method on uploading photo. Let me clearup the understanding. You want to show the loader to intimate the user that he/she has to wait until validation process finishes. Once the validation get success you are starting to upload file. While uploading file, you want to allow the user interact with page.

To achieve this you have to do as follows,

function ajaxSetup(mode) {
    var options = {};
    if (mode === "on") {
        options = {
            beforeSend : function() {
                $("#ajax-loader").dialog({
                    modal : true
                });
            },

            complete : function() {
                $("#ajax-loader").dialog("hide");
            }
        };
    } else {
        options = {
            beforeSend : function() {
            },

            complete : function() {
            }
        };
    }
    $.ajaxSetup(options);
}

And Make your ajax request as follows,

ajaxSetup("on");
$("#send").click(function(e) {
    e.preventDefault();

    $.ajax({
        data : $("#bio-form").serialize(),
        url : "/validate.ajax",
        success : function(response) {
            // If AJAX-validator returns "1" then a form is valid
            if (response == "1") {

                // Now I start to upload photos, like
                // this

                var formData = new FormData(document.getElementById('upload-form'));
                ajaxSetup("off"); //Here second-time seem-less displaying of loader will be avoided.
                $.ajax({
                    processData : false,
                    contentType : false,
                    cache : false,
                    data : formData,
                    success : function(response) {
                        alert(response);
                    }
                });
                ajaxSetup("on");
            }
        }
    });
});

Note: I am not tested code. Please make sure, if any syntax or typo error.

HILARUDEEN S ALLAUDEEN
  • 1,722
  • 1
  • 18
  • 33