0

I want to show loading spinner until a section on the page with images fully loads.

I'm using Django, Jquery and Ajax.

The Html is pretty basic, I have two divs as follows:

enter image description here

On the left side is an table and on the right side is the detail page. I'm trying to show details on user click. When user click on one of the table rows I want to show the corresponding detail page. The onClick event with the ajax call is as follows:

$('.panel-body').on('click', '[data-inspection-row]', function (e) {
    var inspection_id = e.currentTarget.dataset['inspectionId'];
    $.ajax({
        type: "GET",
        url: '/master/inspection_details/' + inspection_id + "/",
        beforeSend: function () {
            $("#details-loader").removeClass("hidden");
        },
        success: function (result) {
            $('#right_side_content').hide().html(result).fadeIn(1000);
            $("#details-loader").addClass("hidden");

        },
        error: function (data) {
            $('#inspection-errors').removeClass('hidden').html(data.responseText);
        }

    })
});

The result that I get in success function comes from an Django template :

{% for picture in data.pictures %}
     <a class="fancybox pad-no thumb" rel="ligthbox" href="{{ picture }}">
            <img class="img-responsive" src="{{ picture }}"/>
     </a>
{% endfor %}

I added beforeSend function which is shown for a milliseconds but I still have a problem with the photos loading.

When I click on one of the table rows on the left I get screen as follows

enter image description here

for about 2-3 seconds and after that the details section loads and I get the screen like on the first image.

Any idea how to show an spinner until the whole right side with all photos is loaded?


The HTML is as follows:

<div class="panel pad-no">
    <div class="panel-body ">
        <div id="left_side" class="col-xl-4 pad-no-lft" style="padding-right: 15px;">
            <!------------ Left side ---------------->
            <div class="panel mar-no bord-no">
                <div id="left_side_content" class="panel-body">

                    <!-------------- Show errors ------------------->
                    <div id="inspection-errors" class="hidden"></div>
                    <!---------------------------------------------->


                    <!------- Show list of all inspections ---------->
                    <div id="inspections-list">
                        <table id="inspections-table" class="table">
                            <thead>
                            {% include "master/inspection_head.html" %}
                            </thead>
                            <tbody id="result">
                            {% for inspection in data %}
                                {% include "master/inspection_body.html" %}
                            {% endfor %}
                            </tbody>
                        </table>
                    </div>
                    -------- End list of all inspections -------->
                </div>
            </div>
            <!------------- End Left side --------------->
        </div>

        <!----------------- Right side -------------------->
        <div id="right_side_container" class="col-xl-8 panel" style="padding: 15px;position: relative;">
            <div id="details-loader" class="hidden spinner"></div>
            <div id="right_side_content"></div>
        </div>
        <div class="clearfix"></div>
    </div>
</div>

UPDATE

I changed the details section (django template) and it is now as follows:

<div id="details-loader" class="spinner"></div>

<div class="panel">
    <div class="panel-body pad-no">
        <div id="inspection-details">
            <div class="wrapper-outter">
                <div class="wrapper-inner" style="margin-left: 0;">
                    {% for picture in data.pictures %}
                        <a class="fancybox pad-no thumb" rel="ligthbox" href="{{ picture }}">
                            <img {% if forloop.last %} id="last-img" {% endif %} class="img-responsive"
                                                       src="{{ picture }}"/>
                        </a>
                    {% endfor %}
                </div>
                <div class="prevArrow"><i class="ti-angle-left icon-2x"></i></div>
                <div class="nextArrow"><i class="ti-angle-right icon-2x"></i></div>
            </div>
        </div>
    </div>
</div>

And jquery to check if the last image is loaded is as follows:

$(document).ready(function () {
    $("#details-loader").show();
    $('img').on('load', function () {
        var id = $(this).attr("id");
        if (id === "last-img") {
           $("#details-loader").hide();
        }
    });
 })

Thus with forloop.last I add an id last-img if it is the last for loop iteration and then I check if the loaded image has that id and if it has it then I hide the spinner.

But the issue is the same. What am I doing wrong?

Boky
  • 11,554
  • 28
  • 93
  • 163
  • Please post the html – RahulB Jul 17 '17 at 08:58
  • https://stackoverflow.com/questions/4494437/jquery-or-javascript-determine-when-image-finished-loading check here – Ivan Jul 17 '17 at 09:01
  • You need to load the images using JavaScript, add an `onload` handler to them, then hide the spinner once all images have loaded. You can do this using promises. –  Jul 17 '17 at 09:04
  • @ChrisG I added an answer with link to that question. – Boky Jul 17 '17 at 12:30
  • @Boky Doesn't matter; your question is still a duplicate. –  Jul 17 '17 at 12:35

2 Answers2

0

1) use load event for images in jquery, consider, that img elements will be created after ready event fired. Use on like in accepted answer here: Event binding on dynamically created elements?

or

2) insert base64 strings on backend instead of urls for images

Ivan
  • 876
  • 1
  • 8
  • 22
0

I found solution on another question here on stackoverflow. Here is the link

jQuery event for images loaded

The library is imagesLoaded and here is the link to the github page

https://github.com/desandro/imagesloaded

I hope that it will help someone else with the same problem.

Boky
  • 11,554
  • 28
  • 93
  • 163