Zachary Weixelbaum
Zachary Weixelbaum

Reputation: 914

Show a spinner for the duration of a Javascript function

I have a function that calls AJAX and it takes approximately 5 seconds for it to finish executing. I have a hidden spinner glyphicon that shows up when the user clicks the button to execute the AJAX via $(".glyphicon-refresh").removeClass("hidden") (hidden is a function in bootstrap and that works fine and it shows the wheel spinning. However, I want that when the function finishes the wheel should be hidden again. But, if I add class hidden at the end of the function or if I do .hide() in jQuery, then the spinning wheel never shows up at all. Is there a way to have a spinning wheel or something show up for the duration of a Javascript function? I searched and only found questions asked for certain frameworks such as MeteorJS, but not just regular code.

EDIT:

Here is part of the code that I am running:

$(document).ready(function() {
    var cont = " .continue-btn";
    $("#section-one" + cont).click({id: "#section-one", next: "#section-two"}, submitSection);
    $("#section-two" + cont).click({id: "#section-two", next: "#section-three"}, submitSection);
});

function submitSection(event) {
    $(event.data.id + " .glyphicon-refresh").removeClass("hidden");
    var there_are_errors = false;
    var radio_element = '';
    var form = event.data.id + ' form';
    $(form + ' input, ' + form + ' select, ' + form + ' radio, ' + form + ' number').each(
        function(i) {
            var input = $(this);
            if (input.is(':radio')) {
                if (this.checked) {
                    //continue
                } else if (radio_element != this.name) {
                    radio_element = this.name;
                    //continue
                } else {
                    there_are_errors = false
                    return false;
                }
            }

            if (typeof(input.attr('class')) == "string" && input.attr('class').indexOf('required') !== -1 && input.val() == '') {
                there_are_errors = false
                return false;
            }
        }
    );
    if (there_are_errors) {
        $(event.data.id + " .glyphicon-refresh").addClass("hidden");
        return false;
    }
    else {
        $.ajax({
            url: '/ajax/form',
            type: 'POST',
            data: $(form).serialize(),
            success: function(data) {
                $(err).removeClass('error-message').text("");
                $(event.data.next + " .section-header").removeClass('disabled').trigger('click');
                if (typeof event.data.submit !== 'undefined') {
                    $("#submit-message p").addClass("submit-message").text(data);
                }
            },
            failure: function(error) {
                $(err).addClass('error-message').text("An error occurred while processing your information.");
                $("html, body").animate({scrollTop: $(event.data.id).offset().top}, 250);
            }
        });
        $(event.data.id + " .glyphicon-refresh").addClass("hidden");
        return true;
    }
}

Upvotes: 1

Views: 1380

Answers (1)

Alex K
Alex K

Reputation: 395

First of all - you should've posted your code. Im assuming you just doing something like this:

function getData() {
  $(".glyphicon-refresh").removeClass("hidden"); // show spinner
  $.ajax(...); // make ajax call
  $(".glyphicon-refresh").addClass("hidden"); // hide spinner
}

This will show spinner and hide it immediately without waiting for ajax function to return, because $.ajax is async. You should do something like this:

function getData() {
  $(".glyphicon-refresh").removeClass("hidden"); // show spinner
  $.ajax(...).always(function() { // .always() will be called after
                                  // ajax request finished 
                                  //(failed or success - doesnt matter)
     $(".glyphicon-refresh").addClass("hidden"); // hide spinner
  }); // make ajax call      
}

Upvotes: 6

Related Questions