1

I'm trying to use a select's onchange event to update the list of contacts in another select. My original code was

function companyUpdated(sel){
    "use strict";
    var id = sel.value;
    $.post("index.php?r=clients/get-client-info&id="+id, function(data) {
        $("#ClientInfo").html(data);
    });
};

I then simply wanted to display a loading div at the beginning and hide it at the end by doing

function companyUpdated(sel){
    "use strict";
    var id = sel.value;
    $("#loading").show();
    $.post("index.php?r=clients/get-client-info&id="+id, function(data) {
        $("#ClientInfo").html(data);
    });
    $("#loading").hide();
};

Now, the code updates the select properly, but I never see the Loading div.

I did all sorts of things and can prove the Loading div is in fact there and can be shown (as it is in other functions...), but not in this specific case.

Now when I swicth the function to use $.ajax, then the div appears correctly. So this is what I ended up with that works.

function companyUpdated(sel){
    "use strict";
    var id = sel.value;
    $("#loading").show();
    $.ajax({
        async: false,
        method: "POST",
        url: "index.php?r=clients/get-client-info&id="+id,
        timeout: 3000,
    })
    .done(
        function(result){
            $("#ClientInfo").html(result);
        }
    );
    $("#loading").hide();
};

My question is why does $.ajax() display the Loading div and not $.post? Is this an expected behavior? I have a solution, but would like to actually understand.

Thank you for taking the time to help!

Still Learning
  • 130
  • 2
  • 12
  • 1
    `$.post` is asynchronous.... you hide immediately after show. Move the hide into success callback. Never ever use `async:false`. It is a horrible practice and is deprecated – charlietfl Jul 17 '19 at 15:45
  • Because of post is async function, when you use loding show then post asyncronius running then loding hide, so hide runs immediately, you should use hide function in post after .html(data) – Ferhat BAŞ Jul 17 '19 at 15:48
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Heretic Monkey Jul 17 '19 at 15:54
  • Thank you both for your answers. I understand now. – Still Learning Jul 17 '19 at 16:36

1 Answers1

1

You need to put $("#loading").hide(); inside the callback function of your ajax/post to call it after the request finished.

Also, remove the async: false from your request.

function companyUpdated(sel){
    var id = sel.value;
    $("#loading").show();
    $.ajax({
        method: "POST",
        url: "index.php?r=clients/get-client-info&id="+id,
        timeout: 3000,
    })
    .done(
        function(result){
            $("#ClientInfo").html(result);
            $("#loading").hide();
        }
    );
};

Using Post:

function companyUpdated(sel){
    var id = sel.value;
    $("#loading").show();
    $.post("index.php?r=clients/get-client-info&id="+id, function(data) {
        $("#ClientInfo").html(data);
        $("#loading").hide();
    });
};

Using Get (just in case):

function companyUpdated(sel){
    var id = sel.value;
    $("#loading").show();
    $.get("index.php?r=clients/get-client-info&id="+id, function(data) {
        $("#ClientInfo").html(data);
        $("#loading").hide();
    });
};

Using Native JavaScript (just in case) - for show/hide animations use CSS:

function companyUpdated(sel){
    var xmlhttp = new XMLHttpRequest();

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == XMLHttpRequest.DONE) {
           if (xmlhttp.status == 200) {
               document.getElementById("ClientInfo").innerHTML = xmlhttp.responseText;
               document.getElementById("loading").style.display = "none";
           }
        }
    };

    document.getElementById("loading").style.display = "block";
    var id = sel.value;
    xmlhttp.open("GET", "index.php?r=clients/get-client-info&id="+id, true);
    xmlhttp.send();
}
MauriceNino
  • 6,214
  • 1
  • 23
  • 60