//
// Author: J. Odeyer
// Date: 2011/03/08
// Last modif date:
//
// This script builds a loading progress widget
//
// Dependencies:
// This class relies on jQuery core library and jQuery UI css
// It extends jQuery object with a CSPprogressWidget plugin function
//js class used to bring the logic to build and display the loading widget
function CSPprogressWidget(container) {
//default values
//properties which can be set and read
this.modal = false;
this.destroyAfterClosing = false;
this.positionContainer = $(document.body); //is the container element that will be used to position the image and to apply the modal div layer
this.loadingImage = '';
this.zIndex = 100;
this.showText = false;
this.text = 'loading...';
this.buildContent = false; //indicates whether image and text have to be build or if they already exist in the provided container element
//properties which should be accessed in read only
this.isDOMcreated = false;
this.container = container; //is the jQuery div element which will contain the loading image
this.modalDiv = null; //overlayer div to make the widget modal
this.isVisible = false;
this.initialCssPosition = 'static';
}
//destroy all elements from DOM
CSPprogressWidget.prototype.destroy = function() {
this.hide();
this.container.removeAttr('cspprogresswidget');
this.container.removeClass('ui-widget');
this.positionContainer.css('position',this.initialCssPosition);
if(this.modalDiv != null) {
this.modalDiv.remove();
}
this.modalDiv = null;
if(this.buildContent) {
this.container.empty();
}
}
//create HTML dom element
CSPprogressWidget.prototype.createHtmlDOM = function() {
if(this.positionContainer[0] !== $(document.body)[0] && this.positionContainer.css('position') == 'static') {
//if positionContainer element position css property is static we make it relative to ensure a right posisioning of all elements
this.positionContainer.css('position','relative');
}
this.container.css({'position': 'absolute','display': 'none', 'zIndex': this.zIndex});
if(this.buildContent) {
//empty container element
this.container.empty();
this.container.css({'text-align':'center'});
//rebuild the content
var imgElt = $('');
imgElt.attr('src',this.loadingImage);
imgElt.attr('alt','loading in progress...');
imgElt.attr('title','loading in progress...');
this.container.append(imgElt);
if(this.showText) {
$('
').appendTo(this.container);
var spanElt = $('');
spanElt.text(this.text);
this.container.append(spanElt);
}
}
if(this.modalDiv != null) {
//we remove the modal overlayer div
this.modalDiv.remove();
}
if(!this.container.hasClass('ui-widget')) {
this.container.addClass('ui-widget');
}
if(this.modal) {
//build the modal overlayer div
this.modalDiv = $('
').addClass('ui-widget-overlay').css({'zIndex': this.zIndex-1, 'display': 'none', 'position': 'absolute', 'top': 0 + 'px', 'left': 0 + 'px'}).appendTo(this.positionContainer);
}
//set isDOMcreated to true
this.isDOMcreated = true;
}
//set position of the widget(loading image + text) //and the modal overlayer
//NB: to get right size and position, element must be displayed
CSPprogressWidget.prototype.setPosition = function() {
var topPosition = 0;
var leftPosition = 0;
var xposContainer = 0;
var yposContainer = 0;
var initialDisplay = this.container.css('display');
//make container visible to ensure we can calculate the position correctly
this.container.css('display','block');
if(this.positionContainer.length>0 && this.positionContainer[0].ownerDocument != null) {
xposContainer = this.positionContainer.offset().left;
}
leftPosition = xposContainer + Math.floor((this.positionContainer.width() - this.container.width()) / 2);
if(this.isTopPosWithPosContainerOk()) {
yposContainer = this.positionContainer.offset().top;
topPosition = yposContainer + Math.floor((this.positionContainer.height() - this.container.height()) / 2);
} else {
topPosition = $(window).scrollTop() + Math.floor(($(window).height() - this.container.height()) / 2);
}
this.container.css({"display": initialDisplay, "top": topPosition + "px", "left": leftPosition + "px"});
}
//check if we can top position the loading widget with the DOM element provided for this.positionContainer
CSPprogressWidget.prototype.isTopPosWithPosContainerOk = function() {
if(this.positionContainer.length<1 || this.positionContainer[0].ownerDocument == null) {
return false;
}
var topPosContainer = this.positionContainer.offset().top;
var bottomPosContainer = this.positionContainer.offset().top + this.positionContainer.height();
var windowTopPos = $(window).scrollTop();
var windowBottomPos = $(window).scrollTop() + $(window).height();
if(topPosContainer < windowTopPos
|| topPosContainer > windowBottomPos
|| bottomPosContainer < windowTopPos
|| bottomPosContainer > windowBottomPos) {
//this.positionContainer DOM element is not fully visible by the current window position, return false
return false;
}
//can be top positioned depending on top position of this.positionContainer element
return true;
}
// allow to access to object properties
// if a value is provided, try to set this property with the provided value and return true if successfull, otherwise return the property value
CSPprogressWidget.prototype.option = function(propertyName, value) {
try {
for(var propName in this) {
if(propName == propertyName) {
if(value != null) {
//value is provided, we set the value
this[propName] = value;
//if an option is set, we recreate DOM
this.createHtmlDOM();
return true;
}
//value is not provided we return the property value
return this[propName];
}
}
if(value == null) {
//if value is not provided, and we have not found the property we return null
return null;
}
} catch(e) {
if(showError != null && showError) {
alert(e);
}
if(value != null) {
return false;
} else {
return null;
}
}
}
//show the loading widget
CSPprogressWidget.prototype.show = function() {
if(!this.isDOMcreated) {
//if DOM has not been created yet, we create it first
this.createHtmlDOM();
}
//set position of the widget(loading image + text) and the modal overlayer
this.setPosition();
if(this.modal && this.modalDiv != null) {
//show the modal overlayer
this.modalDiv.css('display','block');
}
//show the progress widget
this.container.css('display','block');
this.isVisible = true;
}
//hide the loading widget
CSPprogressWidget.prototype.hide = function() {
//hide the progress widget
this.container.css('display','none');
if(this.modalDiv != null) {
//show the modal overlayer
this.modalDiv.css('display','none');
}
this.isVisible = false;
}
//add jQuery extension plugin
jQuery.fn.extend({
//this function returns an object of type CSPprogressWidget with the first matching element, null otherwise
//if an object is passed and the first matching element does not contain an instance of CSPprogressWidget, we create a new instance of CSPprogressWidget initialized with passed object properties
CSPprogressWidget: function(obj) {
if(this.length < 1) {
//jQuery object does not contain any matching element for the selector, return null
return null
}
//get CSPprogressWidget object for the first matching element
if($(this).data('cspprogresswidget') !== undefined)
{
//return $.data(this, 'cspprogresswidget');
return $(this).data('cspprogresswidget');
}
//if CSPprogressWidget attribute does not exists,
//we create a new instance of CSPprogressWidget js class and add a reference to the dom element through an attribute
var CSPprogressWidgetObj = new CSPprogressWidget(this);
if(obj != null) {
if(obj.modal != null) {
CSPprogressWidgetObj.modal = obj.modal;
}
if(obj.destroyAfterClosing != null) {
CSPprogressWidgetObj.destroyAfterClosing = obj.destroyAfterClosing;
}
if(obj.positionContainer != null) {
CSPprogressWidgetObj.positionContainer = $(obj.positionContainer);
}
if(obj.buildContent != null) {
CSPprogressWidgetObj.buildContent = obj.buildContent;
}
if(obj.loadingImage != null) {
CSPprogressWidgetObj.loadingImage = obj.loadingImage;
}
if(obj.zIndex != null) {
CSPprogressWidgetObj.zIndex = obj.zIndex;
}
if(obj.showText != null) {
CSPprogressWidgetObj.showText = obj.showText;
}
if(obj.text != null) {
CSPprogressWidgetObj.text = obj.text;
}
}
//we get initial value for position css property to do a rollback if we have to change it
CSPprogressWidgetObj.initialCssPosition = CSPprogressWidgetObj.positionContainer.css('position');
//associate settings data to the DOM element
$(this).data('cspprogresswidget', CSPprogressWidgetObj);
return CSPprogressWidgetObj;
}
});
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();