macintoshPrime
macintoshPrime

Reputation: 254

Add spinner to input on jquery submit

I'm having some trouble adding a spinner to my search form when the form is submitted. The spinner does eventually show up but only until after the function has completed.

I tried to replicate the error by breaking it down into smaller parts but to no avail. Here the sample code. Any pointers would be appreciated.

<form id="search" class="form-inline">
    <div class="input-group align-bottom" id="address_search">
        <input type="text" name="query" id="query" placeholder="search" class="form-control">       
        <span class="input-group-btn">
            <button class="btn btn-primary" type="submit">
                <i id="search-button" class="fa fa-search" aria-hidden="true"></i>
            </button>
        </span>
    </div>
</form>
$("#search").submit(function() {
    event.preventDefault();

    search = $("#search-button")
    search.removeClass("fa-search")
    search.addClass("fa-spinner fa-spin")

    // Do Something
    for (var i = 0; i < 50000; i++){
        console.log(i)
    }

    // Put Search icon back
    search.removeClass("fa-search")
    search.addClass("fa-spinner fa-pulse")
})

Upvotes: 1

Views: 4691

Answers (2)

NSTuttle
NSTuttle

Reputation: 3345

If you are using Ajax you could use something like the following:

var $spinner = $('#searchButton').hide();
$(document)
.ajaxStart(function () {
    $spinner.show();
})
.ajaxStop(function () {
    $spinner.hide();
});

The ajaxStart and ajaxStop fire per your Ajax call. More on JQuery ajaxStart and ajaxStop found here if interested.

Upvotes: 1

Rory McCrossan
Rory McCrossan

Reputation: 337691

The issue is because the for loop is synchronous and is blocking the UI thread from updating with the class addition/removals you made.

A solution to this is to place the loop in a setTimeout() on a short delay, like this:

$("#search").submit(function(e) {
    e.preventDefault();

    var $search = $("#search-button")
    $search.removeClass("fa-search").addClass("fa-spinner fa-spin")

    setTimeout(function() {
        for (var i = 0; i < 50000; i++){
            console.log(i)
        }

        $search.addClass("fa-search").removeClass("fa-spinner fa-spin")
    }, 50);
})

Working example

Note that you should use the event parameter passed to your event handler, not the global event object. Also, the removeClass()/addClass() logic was backwards after the loop and set the wrong classes, where you state you want to re-instate the fa-search class.

Upvotes: 1

Related Questions