2

On a bootstrap page, when we do some time-consuming task, we usually need a spinning GIF to indicate the process is underway, and block the operational part/changing UI components.

I know jQuery has a plugin called jQuery BlockUI for this specific task, but I am asking myself if we can do it without it, because introducing a plugin for a simple task seems to be a overkill.

Can we?

WesternGun
  • 11,303
  • 6
  • 88
  • 157

2 Answers2

3

For a "lesser-dependency-better" programmer like me, I would not refuse to bring in new friends who can do one thing way better than myself; but, this simple task seems totally a valid trial for my JavaScript skill, because it is relatively easy. So, I spend one hour trying, and what I got was this:

enter image description here

So, it is possible only with jQuery, JavaScript and Bootstrap 3.

When I press a button, my code adds a blocking modal to a table, does a ajax call, and waits 0.5 seconds, then unblocks, in order to show the spinning gif(because it can be too quick to notice). Thanks for @NaveedButt in another question, I found https://icons8.com/preloaders/ to generate a customized gif with the theme color of my site.

Throbber modal: (gif centered horizontally and vertically)

<div id="throbber" class="modal" role="dialog" style="display:none; position:relative; opacity:0.6; background-color:white;">
    <img style="margin: 0 auto;
                position: absolute;
                top: 0; bottom: 0; left:0; right:0;
                margin: auto;
                display: block;" src="/static/images/spinning.gif" />
</div>

The button:

<div class="row">
    <div class="col-lg-12">
        <div class="pull-right">
            <button type="button" id="reload" class="btn btn-primary pull-right-button" style="width: 120px;">Reload</button>
        </div>
    </div>
</div>

JavaScript + jQuery:

function block() {
    var body = $('#panel-body');
    var w = body.css("width");
    var h = body.css("height");
    var trb = $('#throbber');
    var position = body.offset(); // top and left coord, related to document

    trb.css({
        width: w,
        height: h,
        opacity: 0.7,
        position: 'absolute',
        top:        position.top,
        left:       position.left
    });
    trb.show();
}
function unblock() {
    var trb = $('#throbber');
    trb.hide();
}
$(document).ready(function(){
    $('#reload').click(function(){
        block();
        $.ajax({
            type:       "GET",
            url:        "{% url 'scriptsList'%}",
            async:      false
        });
        setTimeout(function(){
            unblock();
        }, 500); //wait 0.5 second to see the spinning gif

    });
});
WesternGun
  • 11,303
  • 6
  • 88
  • 157
1

Yes, what you need is a div with CSS class you will show this div when there is a server call and hide it once this call is done.

function blockPage() {
  $('#divBlock').show();
  setTimeout(function() {
    $('#divBlock').hide();
  }, 3000);
}
.block {
  background: rgba(0, 0, 0, .3) url('https://thumbs.gfycat.com/LameDifferentBalloonfish-max-1mb.gif') no-repeat;
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  background-repeat: no-repeat;
  background-attachment: fixed;
  background-position: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="divBlock" class="block" style="display: none;"></div>
<button type="button" onclick="blockPage()">Block for Loading!</button>
ElasticCode
  • 7,311
  • 2
  • 34
  • 45
  • Good answer... so if we have this BlockUI is not necessary.. In my answer I block the panel body while here you block the whole page, valid too. – WesternGun Mar 27 '18 at 07:39