0

my goal is to display a loading curtain when a query to Quick-Base takes too long.

I have the following code that I thought it was going to work but it somehow does not. Everything works except for the loading curtain because it is never executed when it should be.

My code:

<script>
window.onload = function(){

// .. more code here not related ...

    function selectedValueChanged() {

    $('#curtain').show();   

    var e = document.getElementById("record_id_select");
    var value_selected = e.value;
    var CO_picked_record_id = parseInt(value_selected);
    var query_CO_line_details = "{'"+related_CO_fid+"'.EX.'"+CO_picked_record_id+"'}";
    var records = getRecords(table_CO_line_details_DBID,query_CO_line_details);
    var data_array = createArrayFromRecordsDrilled(records,CO_detail_record_categories);
    var table_div = tableCreate(data_array,'table_container_1',"Please Enter Quantities",headerList);
    $('#table_container_1').replaceWith(table_div);

    $('#curtain').hide();

     }
    }
</script>

<div id='curtain' style='position:absolute;top:0;left:0;margin:0;background:rgba(255,255,255,.3); display:none; width:100%;height:100%;'><img id ="loading_text" src="loader.gif"></div>

</body>

The code works but the curtain is never shown even if the query takes a couple of seconds (as much as 6 seconds). If I comment out the line "$('#curtain').hide();" I can see the loading curtain working as expected but only after the query has finished. It is as if the function is not been executed line by line but it waits first to complete the query and then to show the curtain. I'm sure I'm missing something but I don't know what. Thank you.

Diego Orellana
  • 994
  • 1
  • 9
  • 20
  • 2
    `getRecords` looks like it's synchronous, if so your browsers event queue will get blocked, what this means in simply terms, and UI updates are also blocked. – Keith May 10 '19 at 13:39
  • You should use `window.addEventListener( 'DOMContentLoaded', ... )` instead of `window.onload`, but as you're using jQuery you should use `$( document ).ready()` instead. – Dai May 10 '19 at 13:41

2 Answers2

0

use this instead(no need to add any HTML to page) :

 function showLoading() {
            if (document.getElementById("loadingDiv"))
                return;

            var div = document.createElement("div");
            var img = document.createElement("img");
            var span = document.createElement("span");
            span.appendChild(document.createTextNode("Loading ..."));
            span.style.cssText = "margin-top:50vh;font-family:IranSans;direction:rtl;color:#f78d24;"

            img.src = "/images/LoadingImage.png";
            img.style.cssText = "display:block;margin:auto;margin-top:calc(50vh - 64px);width:128px;height:128px;"

            div.style.cssText = "position:fixed;width:100vw;height:100vh;background-color:rgba(0,0,0,0.85);top:0px;left:0px;z-index:10000;text-align:center";
            div.id = "loadingDiv";
            div.appendChild(img);
            div.appendChild(span);
            document.body.appendChild(div);
        }

        function hideLoading() {
            var div = getElementById("loadingDiv");
            if (div)
                document.body.removeChild(div);
        }
nAviD
  • 2,784
  • 1
  • 33
  • 54
0

The solution as @keith suggested was to "transform" the getRecords function from synchronous to asynchronous.

I ended up making the whole function selectedValueChanged() "asynchronous" by using the setTimeout trick.

One solution that worked for me was the following:

 function selectedValueChanged() {

    var e = document.getElementById("record_id_select");
    var value_selected = e.value;
    var CO_picked_record_id = parseInt(value_selected);
    var query_CO_line_details = "{'"+related_CO_fid+"'.EX.'"+CO_picked_record_id+"'}";
    var records = getRecords(table_CO_line_details_DBID,query_CO_line_details);
    var data_array = createArrayFromRecordsDrilled(records,CO_detail_record_categories);
    var table_div = tableCreate(data_array,'table_container_1',"Please Enter Quantities",headerList);
    $('#table_container_1').replaceWith(table_div);

     }
    }

     function loadingSelectedValueChanged(callbackFunct){

         setTimeout(function(){
             callbackFunct()
             $('#curtain').hide(); 
         },10);
     }

     function selectedValueChangedUP() {

      $('#curtain').show(); 
      loadingSelectedValueChanged(selectedValueChanged);
   }

And now instead of calling selectedValueChanged, I call selectedValueChangedUP.

What SetTimeout does is to execute the function that receives as parameter after a given amount of time. This process is done in an "asynchronous" way.

Diego Orellana
  • 994
  • 1
  • 9
  • 20