Chris@0
|
1 /**
|
Chris@0
|
2 * @file
|
Chris@0
|
3 * Progress bar.
|
Chris@0
|
4 */
|
Chris@0
|
5
|
Chris@17
|
6 (function($, Drupal) {
|
Chris@0
|
7 /**
|
Chris@0
|
8 * Theme function for the progress bar.
|
Chris@0
|
9 *
|
Chris@0
|
10 * @param {string} id
|
Chris@0
|
11 * The id for the progress bar.
|
Chris@0
|
12 *
|
Chris@0
|
13 * @return {string}
|
Chris@0
|
14 * The HTML for the progress bar.
|
Chris@0
|
15 */
|
Chris@17
|
16 Drupal.theme.progressBar = function(id) {
|
Chris@17
|
17 return (
|
Chris@17
|
18 `<div id="${id}" class="progress" aria-live="polite">` +
|
Chris@0
|
19 '<div class="progress__label"> </div>' +
|
Chris@0
|
20 '<div class="progress__track"><div class="progress__bar"></div></div>' +
|
Chris@0
|
21 '<div class="progress__percentage"></div>' +
|
Chris@0
|
22 '<div class="progress__description"> </div>' +
|
Chris@17
|
23 '</div>'
|
Chris@17
|
24 );
|
Chris@0
|
25 };
|
Chris@0
|
26
|
Chris@0
|
27 /**
|
Chris@0
|
28 * A progressbar object. Initialized with the given id. Must be inserted into
|
Chris@0
|
29 * the DOM afterwards through progressBar.element.
|
Chris@0
|
30 *
|
Chris@0
|
31 * Method is the function which will perform the HTTP request to get the
|
Chris@0
|
32 * progress bar state. Either "GET" or "POST".
|
Chris@0
|
33 *
|
Chris@0
|
34 * @example
|
Chris@0
|
35 * pb = new Drupal.ProgressBar('myProgressBar');
|
Chris@0
|
36 * some_element.appendChild(pb.element);
|
Chris@0
|
37 *
|
Chris@0
|
38 * @constructor
|
Chris@0
|
39 *
|
Chris@0
|
40 * @param {string} id
|
Chris@0
|
41 * The id for the progressbar.
|
Chris@0
|
42 * @param {function} updateCallback
|
Chris@0
|
43 * Callback to run on update.
|
Chris@0
|
44 * @param {string} method
|
Chris@0
|
45 * HTTP method to use.
|
Chris@0
|
46 * @param {function} errorCallback
|
Chris@0
|
47 * Callback to call on error.
|
Chris@0
|
48 */
|
Chris@17
|
49 Drupal.ProgressBar = function(id, updateCallback, method, errorCallback) {
|
Chris@0
|
50 this.id = id;
|
Chris@0
|
51 this.method = method || 'GET';
|
Chris@0
|
52 this.updateCallback = updateCallback;
|
Chris@0
|
53 this.errorCallback = errorCallback;
|
Chris@0
|
54
|
Chris@0
|
55 // The WAI-ARIA setting aria-live="polite" will announce changes after
|
Chris@0
|
56 // users
|
Chris@0
|
57 // have completed their current activity and not interrupt the screen
|
Chris@0
|
58 // reader.
|
Chris@0
|
59 this.element = $(Drupal.theme('progressBar', id));
|
Chris@0
|
60 };
|
Chris@0
|
61
|
Chris@17
|
62 $.extend(
|
Chris@17
|
63 Drupal.ProgressBar.prototype,
|
Chris@17
|
64 /** @lends Drupal.ProgressBar# */ {
|
Chris@17
|
65 /**
|
Chris@17
|
66 * Set the percentage and status message for the progressbar.
|
Chris@17
|
67 *
|
Chris@17
|
68 * @param {number} percentage
|
Chris@17
|
69 * The progress percentage.
|
Chris@17
|
70 * @param {string} message
|
Chris@17
|
71 * The message to show the user.
|
Chris@17
|
72 * @param {string} label
|
Chris@17
|
73 * The text for the progressbar label.
|
Chris@17
|
74 */
|
Chris@17
|
75 setProgress(percentage, message, label) {
|
Chris@17
|
76 if (percentage >= 0 && percentage <= 100) {
|
Chris@17
|
77 $(this.element)
|
Chris@17
|
78 .find('div.progress__bar')
|
Chris@17
|
79 .css('width', `${percentage}%`);
|
Chris@17
|
80 $(this.element)
|
Chris@17
|
81 .find('div.progress__percentage')
|
Chris@17
|
82 .html(`${percentage}%`);
|
Chris@17
|
83 }
|
Chris@17
|
84 $('div.progress__description', this.element).html(message);
|
Chris@17
|
85 $('div.progress__label', this.element).html(label);
|
Chris@17
|
86 if (this.updateCallback) {
|
Chris@17
|
87 this.updateCallback(percentage, message, this);
|
Chris@17
|
88 }
|
Chris@17
|
89 },
|
Chris@0
|
90
|
Chris@17
|
91 /**
|
Chris@17
|
92 * Start monitoring progress via Ajax.
|
Chris@17
|
93 *
|
Chris@17
|
94 * @param {string} uri
|
Chris@17
|
95 * The URI to use for monitoring.
|
Chris@17
|
96 * @param {number} delay
|
Chris@17
|
97 * The delay for calling the monitoring URI.
|
Chris@17
|
98 */
|
Chris@17
|
99 startMonitoring(uri, delay) {
|
Chris@17
|
100 this.delay = delay;
|
Chris@17
|
101 this.uri = uri;
|
Chris@17
|
102 this.sendPing();
|
Chris@17
|
103 },
|
Chris@17
|
104
|
Chris@17
|
105 /**
|
Chris@17
|
106 * Stop monitoring progress via Ajax.
|
Chris@17
|
107 */
|
Chris@17
|
108 stopMonitoring() {
|
Chris@17
|
109 clearTimeout(this.timer);
|
Chris@17
|
110 // This allows monitoring to be stopped from within the callback.
|
Chris@17
|
111 this.uri = null;
|
Chris@17
|
112 },
|
Chris@17
|
113
|
Chris@17
|
114 /**
|
Chris@17
|
115 * Request progress data from server.
|
Chris@17
|
116 */
|
Chris@17
|
117 sendPing() {
|
Chris@17
|
118 if (this.timer) {
|
Chris@17
|
119 clearTimeout(this.timer);
|
Chris@17
|
120 }
|
Chris@17
|
121 if (this.uri) {
|
Chris@17
|
122 const pb = this;
|
Chris@17
|
123 // When doing a post request, you need non-null data. Otherwise a
|
Chris@17
|
124 // HTTP 411 or HTTP 406 (with Apache mod_security) error may result.
|
Chris@17
|
125 let uri = this.uri;
|
Chris@17
|
126 if (uri.indexOf('?') === -1) {
|
Chris@17
|
127 uri += '?';
|
Chris@17
|
128 } else {
|
Chris@17
|
129 uri += '&';
|
Chris@17
|
130 }
|
Chris@17
|
131 uri += '_format=json';
|
Chris@17
|
132 $.ajax({
|
Chris@17
|
133 type: this.method,
|
Chris@17
|
134 url: uri,
|
Chris@17
|
135 data: '',
|
Chris@17
|
136 dataType: 'json',
|
Chris@17
|
137 success(progress) {
|
Chris@17
|
138 // Display errors.
|
Chris@17
|
139 if (progress.status === 0) {
|
Chris@17
|
140 pb.displayError(progress.data);
|
Chris@17
|
141 return;
|
Chris@17
|
142 }
|
Chris@17
|
143 // Update display.
|
Chris@17
|
144 pb.setProgress(
|
Chris@17
|
145 progress.percentage,
|
Chris@17
|
146 progress.message,
|
Chris@17
|
147 progress.label,
|
Chris@17
|
148 );
|
Chris@17
|
149 // Schedule next timer.
|
Chris@17
|
150 pb.timer = setTimeout(() => {
|
Chris@17
|
151 pb.sendPing();
|
Chris@17
|
152 }, pb.delay);
|
Chris@17
|
153 },
|
Chris@17
|
154 error(xmlhttp) {
|
Chris@17
|
155 const e = new Drupal.AjaxError(xmlhttp, pb.uri);
|
Chris@17
|
156 pb.displayError(`<pre>${e.message}</pre>`);
|
Chris@17
|
157 },
|
Chris@17
|
158 });
|
Chris@17
|
159 }
|
Chris@17
|
160 },
|
Chris@17
|
161
|
Chris@17
|
162 /**
|
Chris@17
|
163 * Display errors on the page.
|
Chris@17
|
164 *
|
Chris@17
|
165 * @param {string} string
|
Chris@17
|
166 * The error message to show the user.
|
Chris@17
|
167 */
|
Chris@17
|
168 displayError(string) {
|
Chris@17
|
169 const error = $('<div class="messages messages--error"></div>').html(
|
Chris@17
|
170 string,
|
Chris@17
|
171 );
|
Chris@17
|
172 $(this.element)
|
Chris@17
|
173 .before(error)
|
Chris@17
|
174 .hide();
|
Chris@17
|
175
|
Chris@17
|
176 if (this.errorCallback) {
|
Chris@17
|
177 this.errorCallback(this);
|
Chris@17
|
178 }
|
Chris@17
|
179 },
|
Chris@0
|
180 },
|
Chris@17
|
181 );
|
Chris@17
|
182 })(jQuery, Drupal);
|