How to show progress bar while loading, using ajax
Categories:
Displaying Progress Bars During AJAX Requests

Learn how to implement a progress bar to enhance user experience during asynchronous data loading with AJAX, jQuery, and PHP.
When performing asynchronous operations like AJAX requests, users can sometimes be left wondering if anything is happening, especially with slower connections or larger data transfers. Implementing a progress bar or a loading indicator significantly improves the user experience by providing visual feedback that the system is actively working. This article will guide you through creating a simple yet effective progress bar using JavaScript (jQuery) for the frontend and PHP for the backend.
Understanding the Need for Progress Indicators
AJAX (Asynchronous JavaScript and XML) allows web pages to update asynchronously by exchanging small amounts of data with the server behind the scenes. While this improves responsiveness, it can also create a perception of delay if the user isn't aware that an operation is in progress. A progress bar or spinner addresses this by:
- Improving User Experience: Reduces anxiety and uncertainty.
- Providing Feedback: Informs the user that the request has been sent and is being processed.
- Indicating Activity: Prevents users from attempting to re-submit forms or click multiple times, which can lead to duplicate requests or errors.
sequenceDiagram actor User participant Browser participant Server User->>Browser: Initiates AJAX action Browser->>Browser: Show Loading Indicator Browser->>Server: AJAX Request (data) Server-->>Browser: AJAX Response (data) Browser->>Browser: Hide Loading Indicator Browser->>User: Display Updated Content
Sequence diagram of an AJAX request with a loading indicator
Frontend Implementation with jQuery
On the frontend, we'll use jQuery to handle the AJAX request and manipulate the DOM to show and hide our loading indicator. The basic idea is to display the indicator before the AJAX call is made and hide it once the call completes, regardless of success or failure.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AJAX Progress Bar Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
#loading-indicator {
display: none; /* Hidden by default */
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: rgba(0, 0, 0, 0.7);
color: white;
border-radius: 8px;
z-index: 1000;
font-family: Arial, sans-serif;
}
.spinner {
border: 4px solid rgba(255, 255, 255, 0.3);
border-top: 4px solid #fff;
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
margin: 0 auto 10px auto;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#content {
margin-top: 20px;
padding: 15px;
border: 1px solid #ccc;
min-height: 100px;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<h1>AJAX Data Loader</h1>
<button id="loadDataBtn">Load Data</button>
<div id="content"></div>
<div id="loading-indicator">
<div class="spinner"></div>
Loading data...
</div>
<script>
$(document).ready(function() {
$('#loadDataBtn').on('click', function() {
// Show the loading indicator
$('#loading-indicator').show();
$('#content').html(''); // Clear previous content
$.ajax({
url: 'backend.php', // Your PHP script URL
method: 'GET',
data: { delay: 3 }, // Simulate a 3-second delay
success: function(response) {
$('#content').html('<p>Data loaded successfully!</p>' + response);
},
error: function(xhr, status, error) {
$('#content').html('<p>Error loading data: ' + error + '</p>');
console.error("AJAX Error: ", status, error);
},
complete: function() {
// Hide the loading indicator when the request is complete
$('#loading-indicator').hide();
}
});
});
});
</script>
</body>
</html>
HTML structure with a loading indicator and jQuery AJAX call
$(document).ajaxStart()
and $(document).ajaxStop()
to manage a single loading indicator for all AJAX requests on a page, rather than managing it per individual request.Backend Implementation with PHP
The backend PHP script will simulate a delay to demonstrate the progress bar in action. In a real-world application, this would be where your database queries, API calls, or heavy computations would occur.
<?php
// backend.php
// Simulate a delay based on the 'delay' GET parameter
$delay = isset($_GET['delay']) ? (int)$_GET['delay'] : 1;
if ($delay > 0) {
sleep($delay);
}
// Set content type to HTML for demonstration
header('Content-Type: text/html');
// Return some sample data
echo "<p>This content was loaded from the server after a {$delay}-second delay.</p>";
echo "<ul>";
for ($i = 1; $i <= 5; $i++) {
echo "<li>Item {$i}</li>";
}
echo "</ul>";
?>
Simple PHP script to simulate a backend process with a delay
Putting It All Together
To see this in action, save the HTML code as index.html
and the PHP code as backend.php
in the same directory on a web server (e.g., Apache, Nginx with PHP-FPM). When you open index.html
in your browser and click the 'Load Data' button, you will observe the 'Loading data...' indicator appear for a few seconds before the content from backend.php
is displayed.
loading-indicator
content with more sophisticated progress bars (e.g., percentage-based, determinate progress bars) if your backend can provide progress updates. However, for most AJAX requests, a simple indeterminate spinner is sufficient and easier to implement.