Display the HTML element prior to initiating the synchronous AJAX request

I'm looking to display a <div> upon clicking submit before triggering $.ajax()

Here's my HTML:

<div id="waiting_div"></div>

This is the CSS:

#waiting_div {
    position: fixed;
    top: 0px;
    left: 0px;
    height: 100%;
    width: 100%;
    background-color: rgba(0, 0, 0, .8);
    z-index: 999;
    display: block;
}

These are the JavaScript functions:

jQuery(document).ready(function() {
    jQuery("#waiting_div").hide();
});

function set_response_waiting() {
    jQuery("#waiting_div").show();
}
function del_response_waiting() {
    jQuery("#waiting_div").hide();
}

Here's the main JavaScript code:

jQuery("#save_changed_prices").click(function(){
    set_response_waiting(); <-- the div is displayed here

    var len = window.prices.length; //array with data for sending
    var i = 0;

    for (i = 0; i < len; i++) {
        if (window.prices[i].price >= 0) {
            jQuery.ajax({
                type: 'POST',
                url: ajaxurl,
                data: {...... },
                async: false
            }).done(function (data) {
                ...
            }).fail(function () {
                ...
            }).always(function () { 
                ...
            });
        }
    }

    del_response_waiting(); <-- the div is hidden here
});

However, the set_response_waiting() function doesn't display my "#waiting_div" before sending.

I need to refresh or update the DOM tree before sending. Any suggestions on how to achieve this?

The following approach also doesn't work:

jQuery.ajax({
                        type: 'POST',
                        url: ajaxurl,
                        data: {
                            'action': 'update_price',
                            'car_id': car_id,
                            'dep_city_id': window.prices[i].dep,
                            'arr_city_id': window.prices[i].arr,
                            'price': window.prices[i].price
                        }, 
                        beforeSend: set_response_waiting(),
                        async: false
                        })

Answer №1

Ajax operates asynchronously as you likely know, so within your JavaScript function, it progresses directly from set_response_waiting() to del_response_waiting(); the AJAX requests are not executed 'in a linear manner' here. Consider the following approach:

jQuery("#save_changed_prices").click(function(){
        var length = window.prices.length; // array containing data to send
        var index = 0;

        for (index = 0; index < length; index++) {

            if (window.prices[index].price >= 0) {

                jQuery.ajax({
                    type: 'POST',
                    url: ajaxurl,
                    data: {...... },
                    async: false
                }).done(
                    function (data) {
                      del_response_wait(); // hiding the div
                       ...
                    }
                ).fail(function () {
                        ...
                    }
                ).always(set_response_waiting()); // displaying the div here
            }
        }

  });

Answer №2

Utilize, Commit.

When using jQuery ajax, remember that it is an asynchronous method. This means that your function will show and immediately hide.

 jQuery("#save_changed_prices").click(function(){
        set_response_waiting(); <-- display div here

        var len = window.prices.length; //array containing data to be sent
        var i = 0;
        var deferreds = [];

        for (i = 0; i < len; i++) {
            if (window.prices[i].price >= 0) {
                deferreds.push(
                    jQuery.ajax({
                        type: 'POST',
                        url: ajaxurl,
                        data: {...... },
                        async: false
                    }).done(
                        function (data) {
                           ...
                        }
                    ).fail(function () {
                            ...
                        }
                    ).always(function () { ...
                        });
                );
            }
        }
        // wait for all ajax requests to be done.
        $.when.apply(null, deferreds).done(function() {
            del_response_waiting(); <-- hide div
        });
  });

--- UPDATE

 jQuery("#save_changed_prices").click(function(){
        set_response_waiting(); <-- display div here

        var len = window.prices.length; //array containing data to be sent
        var i = 0;
        var deferreds = [];

        for (i = 0; i < len; i++) {
            var deferred = $.Deferred();
            deferreds.push(deferred.promise());

            if (window.prices[i].price >= 0) {
                jQuery.ajax({
                    type: 'POST',
                    url: ajaxurl,
                    data: {...... },
                    async: false
                }).done(
                    function (data) {
                       ...
                    }
                ).fail(function () {
                        ...
                    }
                ).always(function () {
                        deferred.resolve(); // Resolve it here!
                        ...
                    });
                );
            }
        }
        // wait for all ajax requests to be done.
        $.when.apply(null, deferreds).done(function() {
            del_response_waiting(); <-- hide div
        });
  });

---- UPDATE (last)

jQuery("#save_changed_prices").click(function(){
    var send_price = function() {
      var deferreds = [];

      var len = window.prices.length; //array containing data to be sent
      var i = 0;
      for (i = 0; i < len; i++) {
          if (window.prices[i].price >= 0) {
              deferreds.push(
                jQuery.ajax({
                    type: 'POST',
                    url: 'http://jsonplaceholder.typicode.com/posts',
                    data: { price : window.prices[i].price },
                    async: false
                }).done(function (data) {
                    console.log('done', data);
                }).fail(function () {
                    console.error(done, data);
                }).always(function () { 

                })
              );
          }
      }
      $.when.apply(null, deferreds).done(function() {
          del_response_waiting();
      });

    }
    set_response_waiting();
    setTimeout(send_price); // setTimeout for browser to redraw the screen!!

});

View the working example on jsfiddle. :)

https://jsfiddle.net/yourimiyi/rsu4vo3m/

Answer №3

In response to the initial comment made by rsn, it is true that the issue occurs but cannot be resolved in this manner.

To demonstrate how the issue manifests, I have implemented 2-second timeouts in the code below for illustrative purposes:

jQuery("#save_changed_prices").click(function() {
  $('#waiting_div').show();

  setTimeout(function(){
    jQuery.ajax({
      type: 'POST'
    }).done(
      function(data) {
        $('#waiting_div').html('show after ajax submit');
        setTimeout(function(){
            $('#waiting_div').hide();
        }, 2000);
      }
    ).fail(function() {}).always(function() {});
  }, 2000);
});

An example showcasing the issue can be viewed here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Display popup depending on the post's identification number

Currently, I'm in the process of integrating Sanity into my blog. Using the json object returned from a query with useState, I managed to display my posts successfully. However, I am now faced with the challenge of populating a React-Modal with the ap ...

Having trouble retrieving jQuery variables in PHP using POST method

I have a jQuery script in another processing.js file that is included in the HTML file containing the form. $("#1st_submit").on("click", function(event) { var ServiceType = $("#ServiceType").val(); var locality = $("#locality").val(); $.ajax( ...

Using Yii's CArrayDataProvider to set a unique key field for a button's ID within a

Having a two-fold issue here. First, struggling to correctly set the keyField for CArrayDataProvider - only getting back a string instead of a value. Second, attempting to use the keyField within CArrayDataProvider to assign an id to the button in each row ...

Navigating through arrays in JavaScript - optimizing performance

I've noticed this code snippet used in various places: for (var i = 0, len = myArray.length; i < len; i++) { } I understand that this is caching the length of the array. Recently, I encountered this alternative approach: var len = myArray.le ...

Tips for preserving a string in angularJS or Java (and implementing it in an iframe)

My plan involves utilizing a Java web service to fetch the HTML content from a specific URL using Jsoup, and then returning it as a string to the requesting party, which could be an Angular or JS script. I am keen on preserving this content somewhere and l ...

looking to retrieve the corresponding value of a specific array key

I am trying to determine the value of a complex array, but I keep getting values like 0,1,2,3,4,5 as answers. Here is the code snippet I am using to retrieve the state value of the array: var shardState = Object.keys(mydata.cluster.collections[collection ...

What could be causing the parameter to be null when attempting to pass an object using MS AJAX PageMethods?

Here is the snippet I used: PageMethods.MyMethod(JSON.stringify(user), OnMyMethodComplete); Client code: </form> <script type="text/javascript"> var user = { name: "Alice" }; function check() { Page ...

Tips for choosing the class=" * " using jQuery's .html() function

Is there a way to target the string "class" or any other specified string within code retrieved from .html()? If we have an element's HTML content stored in another element (similar to a snippet with preview) <div class="myClass">1</div> ...

Challenges with Vuex and updating arrays using axios

I am currently facing a challenge with VueJS Vuex and Axios: The issue arises when I retrieve an array with Axios and loop through it to populate its children this way: "Rubriques" has many self-relations, so one rubrique can have multiple child rubriques ...

If the div element undergoes a change, use an if-else condition to populate the data fields accordingly

I'm looking to create a basic if/else statement in JavaScript that checks if a div element has changed before populating JSON data fields/variables that pull from dynamically updated HTML. I want to avoid using the deprecated DOMSubtreeModified metho ...

When the webpage is launched, the font styles specified in the CSS do not take effect and

As a beginning coder, I have encountered a small issue. In my HTML document, I attempted to set the font types of my paragraphs and headings to Arial using CSS. The code snippet is as follows: h4{ font-family arial san-serif; } However, when I run the c ...

Search bar that automatically adjusts based on the size of the containing div

https://i.stack.imgur.com/wtn8K.gif I'm interested in learning how to achieve a layout similar to this. Here's an example of what I've created: <div class="header-con"> <div class="search-bar-con"> <input type ...

Guide on Redirecting in Express.js

I am seeking assistance with finding solutions. In short, I have created this API () with username: test and token: test. If the current date is past the meeting time, then open the meeting URL in a new tab. This check should occur every second. ...

Create a custom CSS style to replace the default jQuery hide() function

HTML <div class="adm-input" <?php if(!empty($admin_fee) || $admin_fee != "") echo "style='display:block'"; ?> id="fees-input"> <label>Admission Fees(<i class="fa fa-inr"></i>)</label> <div class="in ...

You can use AJAX, JQuery, or JavaScript in PHP to upload a total of 7 files by utilizing 7 individual file input

My client has a unique request - they want to be able to upload a file in PHP without using the traditional <form> tag or a submit button. While I am familiar with file uploads in PHP, I am unsure of how to achieve this without utilizing the <for ...

Customize Angular Material's Mat-Dialog background blur/darkening effect

Greetings, dear community members, I am currently utilizing angular along with angular material in my projects. By default, when a material dialog is opened, it slightly darkens the background. However, I am interested in having a blurred background inst ...

How to make Vuetify grid columns wrap and fill the full height

I am facing an issue where the component created using v-card in a grid system does not fill the full height. I tried using d-flex but it did not work as expected. The middle column with a white v-card should occupy the entire column height but it is gett ...

Choose the currently active md-tab within the md-dialog's md-tab-group

I need to create a dynamic md-dialog with an md-tab-group that has two tabs. The md-dialog should open based on the button clicked, displaying the corresponding tab content. The initial template where the md-dialog is triggered: <button md-button class ...

Error in jQuery and Canvas Image Crop: The index or size is invalid, exceeding the permissible limit

Recently, I downloaded and installed the Canvas Image Crop plugin from CodeCanyon but encountered a problem specifically on firefox. An error message kept popping up whenever I tried to upload certain images: "Index or size is negative or greater than the ...

Tips for connecting to multiple items in an md-select element from within a directive

Looking to develop a straightforward directive that displays either a textbox or dropdown based on whether an array is provided for the model property on the scope. Any value other than explicitly setting false in the directive markup such as multiple="fa ...