2

I have this code for make a Ajax call:

$.post($form.attr('action'), $form.serialize(), 'json').done(function (data, textStatus, jqXHR) {
    // Some logic here for done callback

    // Redirect to another URL after 5 seconds
    window.setTimeout(function () {
        window.location = data.redirect_to;
    }, 5000);
}).fail(function () {
    // Some logic here for fail callback
})

That code works fine. Now I need to attach a "loader" to this Ajax call. I knew that I can attach this to $(document) as of jQuery 1.8+ docs expose (also found the same on this topic) so I have done the following:

$(function () {
  // a bunch of logic here
}).ajaxStart(function () {
    $('#loaderModal').modal('show');
    $('#loaderModal').on('show.bs.modal', function (e) {
        $('#loaderDiv').loader();
    })
}).ajaxStop(function () {
    $('#loaderModal').modal('hide');
    $('#loaderModal').on('hidden.bs.modal', function (e) {
        $('#loaderDiv').loader('destroy');
    })
});

And once again that works but happens that I have other Ajax calls on the page (for validation purposes on some fields) and every time any of them run then the loader is show which is not correct since I need to attach only to the code shown above (the first piece of code). How I can accomplish this?

As a second part, an related to this post, some of the logic on done and fail callback trigger a Bootstrap Growl message and as you must have noticed I'm using the Twitter Bootstrap Modal component in which the loader is contained, so I'm fear that the call made to run the loader block in some way the second call when the callback for done is invoked, is that even possible? how fast is the execution of these events?

PS: If any of yours have a better solution to this then say and thanks in advance

Community
  • 1
  • 1
ReynierPM
  • 15,161
  • 39
  • 158
  • 314

2 Answers2

2

Why not put your loading scripts into a function so you can call them at will? That way they fit into the logic of your code instead of running every time.

function startLoad() {
    .ajaxStart(function () {
        $('#loaderModal').modal('show');
        $('#loaderModal').on('show.bs.modal', function (e) {
            $('#loaderDiv').loader();
        })
    })
}

function stopLoad() {
    .ajaxStop(function () {
        $('#loaderModal').modal('hide');
        $('#loaderModal').on('hidden.bs.modal', function (e) {
            $('#loaderDiv').loader('destroy');
        })
    });
}
EternalHour
  • 7,327
  • 6
  • 31
  • 54
2

Instead of using the global event handlers, show/hide the loader for the current ajax request like

//show the loader before the request
showLoader();
$.post($form.attr('action'), $form.serialize(), 'json').done(function (data, textStatus, jqXHR) {
    // Some logic here for done callback

    // Redirect to another URL after 5 seconds
    window.setTimeout(function () {
        window.location = data.redirect_to;
    }, 5000);
}).fail(function () {
    // Some logic here for fail callback
}).always(hideLoader) //hide the loader after the ajax request

function showLoader() {
    $('#loaderModal').modal('show');
    $('#loaderModal').on('show.bs.modal', function (e) {
        $('#loaderDiv').loader();
    })
}

function hideLoader() {
    $('#loaderModal').modal('hide');
    $('#loaderModal').on('hidden.bs.modal', function (e) {
        $('#loaderDiv').loader('destroy');
    })
}
Arun P Johny
  • 365,836
  • 60
  • 503
  • 504