Can we spice up the button with some animation while waiting for the ajax call to complete? Just a little something to

My HTML page features a button that triggers an AJAX call when clicked. During the call, the text on the button is replaced with animated dots to indicate progress. However, there is an issue where sometimes the call takes several seconds, while other times it completes in just 0.5 or 1 second. This rapid completion causes a poor user experience, as the text on the button blinks too quickly between the original text and the animated dots.

What can be done to enhance this situation?

Answer №1

Here is an example of a submit event handler. It will immediately finish the animation if a certain amount of time has elapsed. If not, it will wait for that time before completing.

let button_pressed = (e)=>{
    let button = document.getElementById('button_id');
    button.ajaxStarted = new Date().valueOf();

    animate_waiting(); // begin the dot animation effect

    var XHR;
    XHR = new XMLHttpRequest();
    XHR.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200){ // request completed
            let diff = new Date().valueOf() - document.getElementById('button_id').ajaxStarted;
            if(diff < (1000 * 3)){ // less than three seconds have passed
                setTimeout(()=>{
                    call_finished(); // complete the animation and post content
                }, (1000 * 3) - diff);
            }else{ // three seconds have passed
                call_finished(); // complete the animation and post content
            }
        }
    }
    XHR.open("GET", "/your_ajax_call?foo=bar", true);
    XHR.send();
}

Answer №2

To ensure your request call and timeout function are synchronized, you can combine them using the following method in pure JavaScript:

  1. Encapsulate your xhr request in a Promise
var makeRequest = function (url, method) {

    // Create the XHR request
    var request = new XMLHttpRequest();

    // Return it as a Promise
    return new Promise(function (resolve, reject) {

        // Listener to handle completed requests
        request.onreadystatechange = function () {

            // Only run if the request is complete
            if (request.readyState !== 4) return;

            // Process the response
            if (request.status >= 200 && request.status < 300) {
                // Resolve if successful
                resolve(request);
            } else {
                // Reject if failed
                reject({
                    status: request.status,
                    statusText: request.statusText
                });
            }

        };

        // Setup HTTP request
        request.open(method || 'GET', url, true);

        // Send the request
        request.send();

    });
};
  1. Create a waiting function

var justWait = function(interval) {
   return new Promise(resolve => {
      setTimeout(resolve, interval);
   })
}
  1. Combine both functions
// Apply animation here
Promise.all([
    makeRequest('https://some/url/here', 'GET'),
    justWait(1000)
]).then(res => {
    // Remove animation here
})
  .catch(err => {
    // Remove animation in case of error
  });

This ensures that your animation will last at least as long as the justWait interval, but will wait for the xhr request to finish if it takes longer.

If you are using the rxjs library, you can use zip instead of Promise.all, while maintaining the same concept.

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

I am encountering difficulties with a nodejs query where I am unable to successfully include the "+" symbol as part of the query

Every time I submit a query for B+ or A+ {{URL}}/api/help/?bloodType=B+ it ends up showing as empty space, like this. Is there a way to properly pass the "+" sign in the query? Thanks. P.S: _ works fine. {"bloodType":"B "} ...

Generating a 3D path using latitude and longitude coordinates in Three.js

Looking to create a pipe-like structure based on geographic coordinates, the data is in JSON format with latitude and longitude values. Here's an example of how it looks: [ { "LATITUDE": "55.10185525", "LONGITUDE": "-76.4629527" }, { "LAT ...

How can I automatically close the menu when I click on a link in Vue?

Tap the menu icon Select a link The URL changes in the background. However, the menu remains open. How do I close the menu when a link is selected? The menu is wrapped in a details HTML element. Is there a way to remove the "open" attribute from the detai ...

Preventing mouse clicks on checkboxes and triggering events using JavaScript - a complete guide

We have a Table grid with multiple columns, one of which is a Select Box (CheckBox). The expected behavior is that when a row is clicked, the respective CheckBox should get checked, and clicking on the CheckBox itself should update it. I tried implementin ...

The object fails to initialize using data retrieved from the JSONP API

As a newcomer to the world of jQuery and Javascript, I am currently working on creating an object that will store information obtained from an API. The objective is to have this object hold basic info for each user in the users array. My approach involves ...

Using Jquery Ajax for on-focusout and on-submit actions can be tricky, requiring two clicks for the desired outcome

Greetings, I am currently working on a jQuery and Ajax validation form. In this form, if you enter incorrect values like [email protected] for email and 1111111 for password, it will trigger an Ajax validation notice as expected. However, the issue a ...

Concealing particular rows within a table until the Ajax request finishes

On my HTML table, I have certain rows that I don't want to show when the page initially loads. Instead, I plan on making an Ajax request after the page has loaded to retrieve values that will fill in these hidden rows. Therefore, I only want to reveal ...

Avoiding HTML injection in custom directives

In my custom directive, I have implemented the functionality to render strings with LaTeX using MathJax.js. Below is the code snippet: MathJax.Hub.Config({ skipStartupTypeset: true, tex2jax: { inlineMath: [['$','$'], [&ap ...

Leverage the power of Signal R through React with aspnet/signalr integration

I found a helpful resource for incorporating SignalR into react, which you can check out here. However, it seems that the code provided does not align with current standards. The @aspnet/signalr-client has been marked as obsolete and now we are required t ...

Troubleshooting: Issues with Jquery's has, find, contains functions

As I check whether an element contains another element, I've previously utilized the jquery element.has(secondElement) function. In my angularjs project, I make use of jquery within a directive where I transclude elements through markup using ng-tran ...

Having trouble integrating Twilio into your Meteor app? Getting a ReferenceError that says "Twilio is not defined"?

Let me start by saying that I'm new to Meteor and Twilio, so it's likely that I've overlooked something simple. I'm utilizing the Twilio API bindings from this source in an attempt to send an SMS message within a Meteor.methods functio ...

How to Retrieve an Image from a Server Using Node.js and Express

I have successfully implemented a feature to upload images to my server and then store them in the Postgresql database. However, I am facing an issue when trying to display an image on the browser by entering the URL like "http://localhost:5000/photoURL/ ...

Differences in behavior of multiple select with track by in Angular versions above 1.4.x

I recently upgraded my product from Angular 1.2.x to 1.4.x. Since updating to angularjs 1.4.x, I've encountered an issue: What I have: I included code snippets for both angular 1.2.0 and 1.4.8. You can check out the comparison on JSFIDDLE. Explanat ...

What sets apart these watch techniques in AngularJS?

When using a watch in JavaScript, I am encountering an issue. I need to monitor an object within an array, and if any changes occur within the array object, the watch should trigger. However, I am unsure of the best approach to achieve this. Can someone a ...

The AJAX function successfully updates the "points" for the correct clientId, but the datatable value remains unchanged

Is there a way to dynamically update the content of an <h:outputText> element in one column based on the selected value from an <h:selectOneRadio> component located in another column within a datatable? ... <rich:column> ...

Is React capable of storing and recognizing images within its system?

As a junior developer, I find this aspect confusing. Specifically, does reusing the same image on multiple routes in React result in the user downloading it more than once in the browser? I am striving to understand whether using the same image repeatedly ...

What are some ways to make session variables available for sub applications?

I am currently working on setting up an API to interact with a MongoDB database, which I have integrated as a subapplication. In my server controller, I have created a session variable. However, I am facing an issue where the session variables are not be ...

deleting the bottom three rows from a data grid

I currently have a table with two buttons that allow me to add and remove rows from it. Adding a row is simple as I receive 3 rows via ajax each time. Now, the challenge is removing the last three rows of the table by clicking on the remove button. Unles ...

Guide to finding your way to a specific section in React

I attempted to navigate to a particular section within a page. I also tried to include an id in the component, but it didn't function as expected <Login id ="login_section > ...

Tips for assigning a standard or custom value using JavaScript

What is the best way to automatically assign a value of 0 to my input field when the user leaves it blank? Should I use an if statement { } else { } ...