Showing spinner between Bootstrap tabs when loading content with ajax

13,933

As yo are using jQuery.load, you can modify your code like this:

First add a loading div to the page. I usually do something like this:

<div class="loading">
    <img src="/images/loading.gif" />
    <div>Loading</div>
</div>

Give it some CSS to float it to the middle of the screen, style it and initially hide it:

.loading {
    display: none;
    position: fixed;
    top: 350px;
    left: 50%;
    margin-top: -96px;
    margin-left: -96px;
    background-color: #ccc;
    opacity: .85;
    border-radius: 25px;
    width: 192px;
    height: 192px;
    z-index: 99999;
}

Then modify your ajax Javascript:

$('.nav-tabs a').click(function (e) {
    e.preventDefault();
    if ($(this).closest('li').is('.active')) { //stop sending another query when tab active
        return;
    }

    var ts = +new Date();
    var tabUrlAddress = $(this).attr("data-url") + '?timestamp=' + ts;
    var href = this.hash;
    var pane = $(this);
    pane.show();

    //Show the loader
    $(".loading").show();

    $(href).load(tabUrlAddress, function (result) {
        //Hide when complete
        $(".loading").hide();
    });
});
Share:
13,933
akd
Author by

akd

Updated on June 29, 2022

Comments

  • akd
    akd almost 2 years

    I am using bootstrap 3 tabs and using ajax to load the content of each tab on tabbed.

    But sometimes it takes time to load up the content when the server gets slower. Therefore, I would like to put a spinner in the tab content until the server returns the tab content back.

    First of all, is there a built-in easy option to achieve this?( Fade effect is not what I am looking for.)

    If there is not an built-in function to use should I just place a div inside the content and hide/show it when the ajax returns result back?

    Or I should not repeat myself and I should use jquery to place the div element in the active tab and replace it when the ajax done?

    What would be the best option?

      <!-- Nav tabs -->
    <ul class="nav nav-tabs" role="tablist">
      <li class="active"><a href="#home" role="tab" data-toggle="tab">Home</a></li>
      <li><a href="#profile" role="tab" data-toggle="tab">Profile</a></li>
      <li><a href="#messages" role="tab" data-toggle="tab">Messages</a></li>
    </ul>
    
    <!-- Tab panes -->
    <div class="tab-content">
      <div class="tab-pane active" id="home"> <div class="spinner"></div> </div>
      <div class="tab-pane" id="profile"><div class="spinner"></div></div>
      <div class="tab-pane" id="messages"><div class="spinner"></div></div>
    </div>
    

    Here is the ajax query to update content of each tab

    $('.nav-tabs a').click(function (e) {
            e.preventDefault();
            if ($(this).closest('li').is('.active')) { //stop sending another query when tab active
                return;
            }
    
            var ts = +new Date();
            var tabUrlAddress = $(this).attr("data-url") + '?timestamp=' + ts;
            var href = this.hash;
            var pane = $(this);
            pane.show();
    
            $(href).load(tabUrlAddress, function (result) {
    
            });
        });
    
  • akd
    akd almost 10 years
    This is another nice option which I do not have to repeat myself for the loading but I would rather have the spinning inside the clicked tab rather than middle of the whole page. and I believe that the selectors should be as $(".loading") in your code?
  • DavidG
    DavidG almost 10 years
    You could do $(href).html() to set the content of the tab rather than showing the loader. Then you don't need to hide it afterwards. Though it's rather nice to have the same loader across your site and not just for the tabs.