AJAX progress bar

With few lines of JavaScript and CSS you can make simple AJAX progress bar. JavaScript will periodically ask for progress value and server will respond with XML. Progress value should be extracted from the XML and displayed as width of the DIV element. To start progress bar in this example, please click on the Start button and wait for a second to begin. If you have installed Firebug, open Net tab and watch how this page sends request to the Web server.

More precisely, every 1500ms send_request() function sends request to the server (see setInterval line - button actions). ajax-progress-bar.php returns XML and request_handler() processes received XML. Progress value from XML has meaning of percentage completion of a job.

In the following JavaScript source, please focus to the sending and handling requests. Initialization of the XMLHttpRequest is written in the cross-browser manner and there's nothing more to add. The onreadystatechange property is a function that receives the feedback. It is important to note that the feedback function must be assigned before each send, because upon request completion the onreadystatechange property is reset. This is evident in the Mozilla and Firefox source.

var progress;   // progress element reference
var request;    // request object
var intervalID; // interval ID

// button actions
function polling_start() {intervalID = window.setInterval('send_request()',1500)}
function polling_stop()  {window.clearInterval(intervalID)}

// define reference to the progress bar and create request object
window.onload = function (){
	progress = document.getElementById('progress');
	request  = initXMLHttpClient();
}

// create an XMLHttpClient in a cross-browser manner
function initXMLHttpClient(){
	var xmlhttp;
	try {xmlhttp=new XMLHttpRequest()} // Mozilla/Safari/IE7 (normal browsers)
	catch(e){ 												 // IE (?!)
		var success=false;
		var XMLHTTP_IDS=new Array('MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0',
															'MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP');
		for (var i=0; i<XMLHTTP_IDS.length && !success; i++)
			try {success=true; xmlhttp=new ActiveXObject(XMLHTTP_IDS[i])}	catch(e){}
		if (!success) throw new Error('Unable to create XMLHttpRequest!');
	}
	return xmlhttp;
}

// send request to the server
function send_request(){
	request.open('GET','/my/ajax-progress-bar.php', true); // open asynchronus request
	request.onreadystatechange = request_handler;          // set request handler
	request.send(null);                                    // send request
}

// request handler
function request_handler(){
	if (request.readyState == 4){ // if state = 4 (the operation is completed)
		if (request.status == 200){ // and the HTTP status is OK
			// get progress from the XML node and set progress bar width and innerHTML
			var level=request.responseXML.getElementsByTagName('PROGRESS')[0].firstChild;
			progress.style.width = progress.innerHTML = level.nodeValue + '%';
		}
		else{ // if request status is different then 200
			progress.style.width = '100%';
			progress.innerHTML='Error: ['+request.status+'] '+request.statusText;
		}
	}
}

Here you can see how is job progress emulated for this example. In your case you will have to calculate percentage of completion and return it as the XML document.

<?
header('Content-type: text/xml'); // define XML content type
print '<?xml version="1.0"?>';    // print XML header
?>
<DOCUMENT><PROGRESS><?= mktime() % 100 ?></PROGRESS></DOCUMENT>

Bookmark and Share

19 Responses to “AJAX progress bar”

  1. Impressive article ...

  2. Henry Ho says:

    Why XML? Couldn't you have returned the number in plain text instead?

  3. dbunic says:

    Yes, ajax-progress-bar.php could have only one line < ?= mktime() % 100 ?> and in this case progress value should be taken with responseText method (instead of responseXML). Hmm, but then the post should be called "AJA progress bar".
    ;)
    I'm just kidding, I wanted to show how is easy to create the XML communication between client JavaScript and PHP backend. This way you can extend XML and send even more data if you want instead of progress value only.

  4. Bram says:

    Nice article.

    But I have a question: is it possible to stop sending requests when the progress bar has reached 100%?

    Thanks in advance!

  5. Bram says:

    I've found the solution myself (maybe I can help some people with it):

    In request_handler, I check if the progress >= 100, if it is so, I call the function polling_stop().

  6. Your content is awesome. Thanks for the code.

  7. Noel Cinco says:

    I have want to use your progress bar in my web application. And im using JSP as my client side. How can i generate XML from my JSP. and instead of using mktime() method what should i use. Thanks in advance

  8. dbunic says:

    Noel,
    I suppose that the simplest way to create XML from the JSP page is with out.println (JSP experts, please correct me). This page is only demo and shows how to display work progress. In your case (instead of mktime) you will have to build some logic in JSP and return percentage of job done.

  9. Ahmed says:

    Thank you so much,it's a very helpful example.

  10. Wilson says:

    i made a large mysql insert query (500,000+ insert lines) and i want to show the users how far they've gone.
    is it possible to get the current insert point while the insert page is still loading?

  11. Ronny says:

    Thats a very impressive article. But, how do I implement the same in Asp.net? Can U help me out for this?

  12. dbunic says:

    @Wilson - I suppose if you have insert in loop, then you can increase progress value after let's say every 5000 inserts. This progress value should be read in ajax-progress-bar.php. Or just read count(*) of inserted rows, but I'm not sure if MySQL could respond fast with counted rows while inserting at the same time.

    @Ronny - I'm sorry but ASP.NET is not in list of my technologies. Anyway, your main task will be to customize ajax-progress-bar.php to become ajax-progress-bar.aspx (that means to create simple code to output XML). In send_request() function, you will have to rename function call also. I hope that somebody familiar with ASP.NET will help you more.

  13. Mark says:

    Great article. But how exactly do you embed that to html code. Say I want to execute a command on the server on the click of a button on the page which javascript function do I need to run. Can you please help. Many thanks!

  14. Mark says:

    What does ajax-progress-bar.php do?

  15. Janki says:

    This is not working under IE6... can anyone help me?

  16. dbunic says:

    @Mark - Please see the request_handler() function. After browser got reply from the server, element width changes according to the PROGRESS value in XML. To execute command on the server on the button click, you can use classic post-back approach or you can try with AJAX. AJAX can send request to the server in "background", so the current page will not refresh. To start with AJAX, you can use initXMLHttpClient(), send_request() and request_handler() functions. Please do not forget to initialize XMLHttpClient object before sending request.

    In this example, ajax-progress-bar.php emulates progress of some server work. Actually, it only generates XML with progress value.

    @Janki - Demo in this post should work in IE6. I test it with IETester and it works. Please try to click on the button "Start" and wait few seconds. Progress bar should grow every 1.5 seconds.

  17. [...] Demo  Tutorial  Posted in ajax | Tags: ajax, ajax progress bar, progress bar, simple progress bar « JavaScript dialog box You can leave a response, or trackback from your own site. [...]

  18. Nick says:

    Hi,
    what does your ajax-progress-bar.php do?

  19. dbunic says:

    @Nick - ajax-progress-bar.php emulates some job progress. Actually it calculates percentage based on current time for this demo. Simply enough to show a communication between server side and AJAX JavaScript.

Leave a Reply