/* --------------------------------------------------------------
loading_spinner.js 2016-06-15
Gambio GmbH
http://www.gambio.de
Copyright (c) 2016 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
*/
jse.libs.loading_spinner = jse.libs.loading_spinner || {};
/**
* ## Loading Spinner Library
*
* This library provides an easy and simple way to display a loading spinner inside any container
* element to provide a smooth "loading" experience to the UI. If no container is specified then
* the whole page will be taken for the display. The loading spinner comes from the Font Awesome
* "fa-spinner" class. You can load this library as a dependency to existing modules.
*
* The following usage example will show you how to display and hide the spinner inside an element.
*
* ```javascript
* // Create a selector variable for the target element.
* var $targetElement = $('#my-div');
*
* // The $targetElement will be overlayed by the spinner.
* var $spinner = window.jse.libs.loading_spinner.show($targetElement);
*
* // Do some stuff ...
*
* // Hide the spinner when the job is done.
* window.jse.loading_spinner.hide($spinner);
* ```
*
* @module JSE/Libs/loading_spinner
* @exports jse.libs.loading_spinner
*/
(function (exports) {
'use strict';
/**
* Contains a list of the active spinners so that they can be validated
* before they are destroyed.
*
* @type {Array}
*/
const instances = [];
/**
* Show the loading spinner to the target element.
*
* @param {jQuery} $targetElement (optional) The target element will be overlayed by the spinner. If no
* argument is provided then the spinner will overlay the whole page.
* @param {String} zIndex Optional ('auto'), give a specific z-index value to the loading spinner.
*
* @return {jQuery} Returns the selector of the spinner div element. You can further manipulate the spinner
* if required, but you have to provide this selector as a parameter to the "hide" method below.
*/
exports.show = function ($targetElement, zIndex = 'auto') {
if ($targetElement !== undefined && typeof $targetElement !== 'object') {
throw new Error('Invalid argument provided for the "show" method: ' + typeof $targetElement);
}
if ($targetElement.length === 0) {
return; // No element matches the provided selector.
}
$targetElement = $targetElement || $('body'); // set default value
const $spinner = $('<div class="loading-spinner"></div>');
const fontSize = 80;
$spinner
.html('<i class="fa fa-spinner fa-pulse"></i>')
.css({
width: $targetElement.innerWidth() + 'px',
height: $targetElement.innerHeight() + 'px',
boxSizing: 'border-box',
background: '#FFF',
opacity: '0.8',
position: 'absolute',
top: $targetElement.offset().top,
left: $targetElement.offset().left,
fontSize: fontSize + 'px',
color: '#002337', // primary color
zIndex: zIndex
})
.appendTo('body');
$spinner.find('i').css({
position: 'absolute',
left: $spinner.width() / 2 - fontSize / 2,
top: $spinner.height() / 2 - fontSize / 2
});
instances.push($spinner);
return $spinner;
};
/**
* Hide an existing spinner.
*
* This method will hide and remove the loading spinner markup from the document entirely.
*
* @param {jQuery} $spinner Must be the selector provided from the "show" method. If the selector
* is invalid or no elements were found then an exception will be thrown.
*
* @return {jQuery.Promise} Returns a promise object that will be resolved once the spinner is removed.
*
* @throws Error If the $spinner selector was not found in the spinner instances.
*/
exports.hide = function ($spinner) {
const index = instances.indexOf($spinner);
const deferred = $.Deferred();
if (index === -1) {
throw new Error('The provided spinner instance does not exist.');
}
instances.splice(index, 1);
$spinner.fadeOut(400, function () {
$spinner.remove();
deferred.resolve();
});
return deferred.promise();
};
})(jse.libs.loading_spinner);