summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Carver2013-04-22 19:14:34 (GMT)
committer Mark Carver2013-04-22 19:14:34 (GMT)
commit45193865c42157cf11b6e91adab1a429b70f4333 (patch)
tree3e92a92c32172fd4e96d530518bc87592f37f862
parenta26149d5c63b8534d07cd6d7377befe277a8eaf6 (diff)
Issue #1950694 by Mark Carver: Use Bootstrap's progress bar
-rw-r--r--css/style.css9
-rw-r--r--includes/theme.inc21
-rw-r--r--js/progress.js106
3 files changed, 136 insertions, 0 deletions
diff --git a/css/style.css b/css/style.css
index ac05a6a..f6a8df4 100644
--- a/css/style.css
+++ b/css/style.css
@@ -226,3 +226,12 @@ e.g. multipage*/
.form-actions{
clear: both;
}
+
+/* Progress Bar Overrides */
+.progress-wrapper .progress {
+ margin-bottom: 10px;
+}
+.progress-wrapper .progress .bar {
+ border: 0 none;
+ margin: 0;
+} \ No newline at end of file
diff --git a/includes/theme.inc b/includes/theme.inc
index 4152e2b..3ea5c96 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -297,6 +297,13 @@ function bootstrap_js_alter(&$js) {
if (module_exists('bootstrap_ui')) {
libraries_load('bootstrap', 'minified');
}
+
+ // Replace core progress bar JS with the Bootstrap equivilent.
+ if (isset($js['misc/progress.js']) && !empty($js['misc/progress.js'])) {
+ unset($js['misc/progress.js']);
+ $progress = drupal_get_path('theme', 'bootstrap') . '/js/progress.js';
+ $js[$progress] = drupal_js_defaults($progress);
+ }
$js = array_diff_key($js, $excludes);
if (theme_get_setting('cdn_bootstrap')) {
@@ -331,6 +338,20 @@ function _bootstrap_alter($files, $type) {
}
/**
+ * Returns HTML for Bootstrap's progress bar.
+ */
+function bootstrap_progress_bar($variables) {
+ $output .= '<div id="progress" class="progress-wrapper">';
+ $output .= ' <div class="progress progress-striped progress-info active">';
+ $output .= ' <div class="bar" style="width: ' . $variables['percent'] . '%"></div>';
+ $output .= ' </div>';
+ $output .= ' <div class="percentage pull-right">' . $variables['percent'] . '%</div>';
+ $output .= ' <div class="message">' . $variables['message'] . '</div>';
+ $output .= '</div>';
+ return $output;
+}
+
+/**
* Returns HTML for Bootstrap's modal.
*/
function bootstrap_bootstrap_modal($variables) {
diff --git a/js/progress.js b/js/progress.js
new file mode 100644
index 0000000..cf6893e
--- /dev/null
+++ b/js/progress.js
@@ -0,0 +1,106 @@
+(function ($) {
+
+/**
+ * A progressbar object. Initialized with the given id. Must be inserted into
+ * the DOM afterwards through progressBar.element.
+ *
+ * method is the function which will perform the HTTP request to get the
+ * progress bar state. Either "GET" or "POST".
+ *
+ * e.g. pb = new progressBar('myProgressBar');
+ * some_element.appendChild(pb.element);
+ */
+Drupal.progressBar = function (id, updateCallback, method, errorCallback) {
+ var pb = this;
+ this.id = id;
+ this.method = method || 'GET';
+ this.updateCallback = updateCallback;
+ this.errorCallback = errorCallback;
+
+ // The WAI-ARIA setting aria-live="polite" will announce changes after users
+ // have completed their current activity and not interrupt the screen reader.
+ this.element = $('<div class="progress-wrapper" aria-live="polite"></div>');
+ this.element.html('<div id ="' + id + '" class="progress progress-striped progress-info active"><div class="bar"></div></div>' +
+ '<div class="percentage pull-right"></div>' +
+ '<div class="message">&nbsp;</div>');
+};
+
+/**
+ * Set the percentage and status message for the progressbar.
+ */
+Drupal.progressBar.prototype.setProgress = function (percentage, message) {
+ if (percentage >= 0 && percentage <= 100) {
+ $('div.bar', this.element).css('width', percentage + '%');
+ $('div.percentage', this.element).html(percentage + '%');
+ }
+ $('div.message', this.element).html(message);
+ if (this.updateCallback) {
+ this.updateCallback(percentage, message, this);
+ }
+};
+
+/**
+ * Start monitoring progress via Ajax.
+ */
+Drupal.progressBar.prototype.startMonitoring = function (uri, delay) {
+ this.delay = delay;
+ this.uri = uri;
+ this.sendPing();
+};
+
+/**
+ * Stop monitoring progress via Ajax.
+ */
+Drupal.progressBar.prototype.stopMonitoring = function () {
+ clearTimeout(this.timer);
+ // This allows monitoring to be stopped from within the callback.
+ this.uri = null;
+};
+
+/**
+ * Request progress data from server.
+ */
+Drupal.progressBar.prototype.sendPing = function () {
+ if (this.timer) {
+ clearTimeout(this.timer);
+ }
+ if (this.uri) {
+ var pb = this;
+ // When doing a post request, you need non-null data. Otherwise a
+ // HTTP 411 or HTTP 406 (with Apache mod_security) error may result.
+ $.ajax({
+ type: this.method,
+ url: this.uri,
+ data: '',
+ dataType: 'json',
+ success: function (progress) {
+ // Display errors.
+ if (progress.status == 0) {
+ pb.displayError(progress.data);
+ return;
+ }
+ // Update display.
+ pb.setProgress(progress.percentage, progress.message);
+ // Schedule next timer.
+ pb.timer = setTimeout(function () { pb.sendPing(); }, pb.delay);
+ },
+ error: function (xmlhttp) {
+ pb.displayError(Drupal.ajaxError(xmlhttp, pb.uri));
+ }
+ });
+ }
+};
+
+/**
+ * Display errors on the page.
+ */
+Drupal.progressBar.prototype.displayError = function (string) {
+ var error = $('<div class="alert alert-block alert-error"><a class="close" data-dismiss="alert" href="#">&times;</a><h4>Error message</h4></div>').append(string);
+ $(this.element).before(error).hide();
+
+ if (this.errorCallback) {
+ this.errorCallback(this);
+ }
+};
+
+})(jQuery);