initial import from onelab svn codebase
[plewww.git] / misc / progress.js
1 // $Id: progress.js 144 2007-03-28 07:52:20Z thierry $
2
3 /**
4  * A progressbar object. Initialized with the given id. Must be inserted into
5  * the DOM afterwards through progressBar.element.
6  *
7  * method is the function which will perform the HTTP request to get the
8  * progress bar state. Either HTTPGet or HTTPPost.
9  *
10  * e.g. pb = new progressBar('myProgressBar');
11  *      some_element.appendChild(pb.element);
12  */
13 function progressBar(id, updateCallback, method, errorCallback) {
14   var pb = this;
15   this.id = id;
16   this.method = method ? method : HTTPGet;
17   this.updateCallback = updateCallback;
18   this.errorCallback = errorCallback;
19
20   this.element = document.createElement('div');
21   this.element.id = id;
22   this.element.className = 'progress';
23   this.element.innerHTML = '<div class="percentage"></div>'+
24                            '<div class="message">&nbsp;</div>'+
25                            '<div class="bar"><div class="filled"></div></div>';
26 }
27
28 /**
29  * Set the percentage and status message for the progressbar.
30  */
31 progressBar.prototype.setProgress = function (percentage, message) {
32   var divs = this.element.getElementsByTagName('div');
33   var div;
34   for (var i = 0; div = divs[i]; ++i) {
35     if (percentage >= 0) {
36       if (hasClass(divs[i], 'filled')) {
37         divs[i].style.width = percentage + '%';
38       }
39       if (hasClass(divs[i], 'percentage')) {
40         divs[i].innerHTML = percentage + '%';
41       }
42     }
43     if (hasClass(divs[i], 'message')) {
44       divs[i].innerHTML = message;
45     }
46   }
47   if (this.updateCallback) {
48     this.updateCallback(percentage, message, this);
49   }
50 }
51
52 /**
53  * Start monitoring progress via Ajax.
54  */
55 progressBar.prototype.startMonitoring = function (uri, delay) {
56   this.delay = delay;
57   this.uri = uri;
58   this.sendPing();
59 }
60
61 /**
62  * Stop monitoring progress via Ajax.
63  */
64 progressBar.prototype.stopMonitoring = function () {
65   clearTimeout(this.timer);
66   // This allows monitoring to be stopped from within the callback
67   this.uri = null;
68 }
69
70 /**
71  * Request progress data from server.
72  */
73 progressBar.prototype.sendPing = function () {
74   if (this.timer) {
75     clearTimeout(this.timer);
76   }
77   if (this.uri) {
78     this.method(this.uri, this.receivePing, this, '');
79   }
80 }
81
82 /**
83  * HTTP callback function. Passes data back to the progressbar and sets a new
84  * timer for the next ping.
85  */
86 progressBar.prototype.receivePing = function (string, xmlhttp, pb) {
87   if (xmlhttp.status != 200) {
88     return pb.displayError('An HTTP error '+ xmlhttp.status +' occured.\n'+ pb.uri);
89   }
90   // Parse response
91   var progress = parseJson(string);
92   // Display errors
93   if (progress.status == 0) {
94     pb.displayError(progress.data);
95     return;
96   }
97
98   // Update display
99   pb.setProgress(progress.percentage, progress.message);
100   // Schedule next timer
101   pb.timer = setTimeout(function() { pb.sendPing(); }, pb.delay);
102 }
103
104 /**
105  * Display errors on the page.
106  */
107 progressBar.prototype.displayError = function (string) {
108   var error = document.createElement('div');
109   error.className = 'error';
110   error.innerHTML = string;
111
112   this.element.style.display = 'none';
113   this.element.parentNode.insertBefore(error, this.element);
114
115   if (this.errorCallback) {
116     this.errorCallback(this);
117   }
118 }