0

I have a button on the html page, when user clicks on it part of the html form should be cloned and processed in certain way. Cloning and processing takes some time and I would like to display loader.

  $(".dashed_button.add_supplier").click(function(){

        $(".supply-details-tab .inner_tab .supplier_info_link").last().after('<div class="loader"></div>');

        //Create new tab link
        var newTabLink = $(".inner_tab .supplier_info_link").last().clone();
        $(".inner_tab .supplier_info_link").removeClass("active");
        $(newTabLink).addClass("active");

        //Get last existing index
        var lastIndex= parseInt($(newTabLink).attr('id').substring(14));
        var newIndex = lastIndex+1;
        var lastExistingTab = $(".supply-details-tab .tab-pane").last().find("> .subform_fields_wrapper");


        cloningSupplyDetails($(lastExistingTab), $("#supplier_"+newIndex));

        $(".supply-details-tab .inner_tab .loader").remove();
    });

The problem is that after click button is frozen, no loader is displayed and the user cannot understand what is happening. After some time new cloned subform is displayed.

How can I stop the button from freezing and display a loader during function execution?

user2019037
  • 764
  • 1
  • 7
  • 14
Tamara
  • 2,910
  • 6
  • 44
  • 73

1 Answers1

0

You are the victim of synchronous functions, which hang until complete.


In synchronous code, every single line is run one after the other, meaning that the function is not allowed to complete until every single line is called.

User presses button:

  1. Show loading
  2. Do stuff
  3. Hide loading
  4. Return stuff
  5. UI Update
  6. Exit

The UI will update somewhere after 4. This is normally not a problem, because most code can be run synchronously without issues, and it makes sense in a lot of cases, but in your case, you probably want a multi-threaded layout:

User presses button:

 Thread 1:

   1. Show loading
   2. UI Update
   3. Exit

 Thread 2:

   1. Do stuff
   2. Hide loading
   3. Return stuff
   4. UI Update
   5. Exit.

They would then be called asynchronously in the order of:

  1. Thread 1
  2. Thread 2

Asynchronously

refers to calling a block of code on a thread separate to the calling thread. You may be familiar with this if you have ever used the setTimeout or setInterval methods.

You may run code like this:

var i = 1;

setTimeout(function(){
    $("div.red").addClass(".blue");
}, 500);

return i;

What happens here is that i is declared as 1, returned, and then .5s later, div.red becomes div.red.blue. The function in the timeout is called asynchronously half a second after i is returned; therefore, it is not required to complete before i is returned.

This is what you want to happen in your code.


So what you want to do is show the loading first; then using an asynchronous call, such as setTimeout with a delay of 1, do all of your cloning, processing, etc. When that is done, you may hide the loading. That will keep your UI from freezing while the processing is done.

It would be something like this:

$(".loading").show();

setTimeout(function(){

    //Process stuff
    $(".loading").hide();

}, 1);

Other examples of asynchronous JavaScript

Community
  • 1
  • 1
Liftoff
  • 24,717
  • 13
  • 66
  • 119