core/skin/plugins/notifications/js/lobibox.js

1576 lines
56 KiB
JavaScript
Executable File

//Author : @arboshiki
//create lobibox object
var Lobibox = Lobibox || {};
(function () {
Lobibox.counter = 0;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//User can set default properties for prompt in the following way
//Lobibox.prompt.DEFAULT_OPTIONS = object;
Lobibox.prompt = function (type, options) {
return new LobiboxPrompt(type, options);
};
//User can set default properties for confirm in the following way
//Lobibox.confirm.DEFAULT_OPTIONS = object;
Lobibox.confirm = function (options) {
return new LobiboxConfirm(options);
};
//User can set default properties for progress in the following way
//Lobibox.progress.DEFAULT_OPTIONS = object;
Lobibox.progress = function (options) {
return new LobiboxProgress(options);
};
//Create empty objects in order user to be able to set default options in the following way
//Lobibox.error.DEFAULT_OPTIONS = object;
//Lobibox.success.DEFAULT_OPTIONS = object;
//Lobibox.warning.DEFAULT_OPTIONS = object;
//Lobibox.info.DEFAULT_OPTIONS = object;
Lobibox.error = {};
Lobibox.success = {};
Lobibox.warning = {};
Lobibox.info = {};
//User can set default properties for alert in the following way
//Lobibox.alert.DEFAULT_OPTIONS = object;
Lobibox.alert = function (type, options) {
if (["success", "error", "warning", "info"].indexOf(type) > -1) {
return new LobiboxAlert(type, options);
}
};
//User can set default properties for window in the following way
//Lobibox.window.DEFAULT_OPTIONS = object;
Lobibox.window = function (options) {
return new LobiboxWindow('window', options);
};
/**
* Base prototype for all messageboxes and window
*/
var LobiboxBase = {
$type: null,
$el: null,
$options: null,
debug: function () {
if (this.$options.debug) {
window.console.debug.apply(window.console, arguments);
}
},
_processInput: function (options) {
if ($.isArray(options.buttons)) {
var btns = {};
for (var i = 0; i < options.buttons.length; i++) {
btns[options.buttons[i]] = Lobibox.base.OPTIONS.buttons[options.buttons[i]];
}
options.buttons = btns;
}
options.customBtnClass = options.customBtnClass ? options.customBtnClass : Lobibox.base.DEFAULTS.customBtnClass;
for (var i in options.buttons) {
if (options.buttons.hasOwnProperty(i)) {
var btn = options.buttons[i];
btn = $.extend({}, Lobibox.base.OPTIONS.buttons[i], btn);
if (!btn['class']) {
btn['class'] = options.customBtnClass;
}
options.buttons[i] = btn;
}
}
options = $.extend({}, Lobibox.base.DEFAULTS, options);
if (options.showClass === undefined) {
options.showClass = Lobibox.base.OPTIONS.showClass;
}
if (options.hideClass === undefined) {
options.hideClass = Lobibox.base.OPTIONS.hideClass;
}
if (options.baseClass === undefined) {
options.baseClass = Lobibox.base.OPTIONS.baseClass;
}
if (options.delayToRemove === undefined) {
options.delayToRemove = Lobibox.base.OPTIONS.delayToRemove;
}
if (!options.iconClass) {
options.iconClass = Lobibox.base.OPTIONS.icons[options.iconSource][this.$type];
}
return options;
},
_init: function () {
var me = this;
me._createMarkup();
me.setTitle(me.$options.title);
if (me.$options.draggable && !me._isMobileScreen()) {
me.$el.addClass('draggable');
me._enableDrag();
}
if (me.$options.closeButton) {
me._addCloseButton();
}
if (me.$options.closeOnEsc) {
$(document).on('keyup.lobibox', function (ev) {
if (ev.which === 27) {
me.destroy();
}
});
}
if (me.$options.baseClass) {
me.$el.addClass(me.$options.baseClass);
}
if (me.$options.showClass) {
me.$el.removeClass(me.$options.hideClass);
me.$el.addClass(me.$options.showClass);
}
me.$el.data('lobibox', me);
},
/**
* Calculate top, left position based on string keyword
*
* @param {string} position "'top', 'center', 'bottom'"
* @returns {{left: number, top: number}}
* @private
*/
_calculatePosition: function (position) {
var me = this;
var top;
if (position === 'top') {
top = 30;
} else if (position === 'bottom') {
top = $(window).outerHeight() - me.$el.outerHeight() - 30;
} else {
top = ($(window).outerHeight() - me.$el.outerHeight()) / 2;
}
var left = ($(window).outerWidth() - me.$el.outerWidth()) / 2;
return {
left: left,
top: top
};
},
_createButton: function (type, op) {
var me = this;
var btn = $('<button></button>')
.addClass(op['class'])
.attr('data-type', type)
.html(op.text);
if (me.$options.callback && typeof me.$options.callback === 'function') {
btn.on('click.lobibox', function (ev) {
var bt = $(this);
me._onButtonClick(me.$options.buttons[type], type);
me.$options.callback(me, bt.data('type'), ev);
});
}
btn.click(function () {
me._onButtonClick(me.$options.buttons[type], type);
});
return btn;
},
_onButtonClick: function (buttonOptions, type) {
var me = this;
if ((type === 'ok' && me.$type === 'prompt' && me.isValid() || me.$type !== 'prompt' || type !== 'ok')
&& buttonOptions && buttonOptions.closeOnClick) {
me.destroy();
}
},
_generateButtons: function () {
var me = this;
var btns = [];
for (var i in me.$options.buttons) {
if (me.$options.buttons.hasOwnProperty(i)) {
var op = me.$options.buttons[i];
var btn = me._createButton(i, op);
btns.push(btn);
}
}
return btns;
},
_createMarkup: function () {
var me = this;
var lobibox = $('<div class="lobibox"></div>');
lobibox.attr('data-is-modal', me.$options.modal);
var header = $('<div class="lobibox-header"></div>')
.append('<span class="lobibox-title"></span>')
;
var body = $('<div class="lobibox-body"></div>');
lobibox.append(header);
lobibox.append(body);
if (me.$options.buttons && !$.isEmptyObject(me.$options.buttons)) {
var footer = $('<div class="lobibox-footer"></div>');
footer.append(me._generateButtons());
lobibox.append(footer);
if (Lobibox.base.OPTIONS.buttonsAlign.indexOf(me.$options.buttonsAlign) > -1) {
footer.addClass('text-' + me.$options.buttonsAlign);
}
}
me.$el = lobibox
.addClass(Lobibox.base.OPTIONS.modalClasses[me.$type])
;
},
_setSize: function () {
var me = this;
me.setWidth(me.$options.width);
if (me.$options.height === 'auto') {
me.setHeight(me.$el.outerHeight());
} else {
me.setHeight(me.$options.height);
}
},
_calculateBodyHeight: function (height) {
var me = this;
var headerHeight = me.$el.find('.lobibox-header').outerHeight();
var footerHeight = me.$el.find('.lobibox-footer').outerHeight();
return height - (headerHeight ? headerHeight : 0) - (footerHeight ? footerHeight : 0);
},
/**
* Add backdrop in case if backdrop does not exist
*
* @private
*/
_addBackdrop: function () {
if ($('.lobibox-backdrop').length === 0) {
$('body').append('<div class="lobibox-backdrop"></div>');
}
},
_triggerEvent: function (type) {
var me = this;
if (me.$options[type] && typeof me.$options[type] === 'function') {
me.$options[type](me);
}
},
_calculateWidth: function (width) {
var me = this;
width = Math.min(Math.max(width, me.$options.width), $(window).outerWidth());
if (width === $(window).outerWidth()) {
width -= 2 * me.$options.horizontalOffset;
}
return width;
},
_calculateHeight: function (height) {
var me = this;
console.log(me.$options.height);
height = Math.min(Math.max(height, me.$options.height), $(window).outerHeight());
if (height === $(window).outerHeight()) {
height -= 2 * me.$options.verticalOffset;
}
return height;
},
_addCloseButton: function () {
var me = this;
var closeBtn = $('<span class="btn-close">&times;</span>');
me.$el.find('.lobibox-header').append(closeBtn);
closeBtn.on('mousedown', function (ev) {
ev.stopPropagation();
});
closeBtn.on('click.lobibox', function () {
me.destroy();
});
},
_position: function () {
var me = this;
me._setSize();
var pos = me._calculatePosition();
me.setPosition(pos.left, pos.top);
},
_isMobileScreen: function () {
return $(window).outerWidth() < 768;
},
_enableDrag: function () {
var el = this.$el,
heading = el.find('.lobibox-header');
heading.on('mousedown.lobibox', function (ev) {
el.attr('offset-left', ev.offsetX);
el.attr('offset-top', ev.offsetY);
el.attr('allow-drag', 'true');
});
$(document).on('mouseup.lobibox', function () {
el.attr('allow-drag', 'false');
});
$(document).on('mousemove.lobibox', function (ev) {
if (el.attr('allow-drag') === 'true') {
var left = ev.clientX - parseInt(el.attr('offset-left'), 10) - parseInt(el.css('border-left-width'), 10);
var top = ev.clientY - parseInt(el.attr('offset-top'), 10) - parseInt(el.css('border-top-width'), 10);
el.css({
left: left,
top: top
});
}
});
},
/**
* Set the message of messagebox
*
* @param {string} msg "new message of messagebox"
* @returns {LobiboxBase}
* @private
*/
_setContent: function (msg) {
var me = this;
me.$el.find('.lobibox-body').html(msg);
return me;
},
_beforeShow: function () {
var me = this;
me._triggerEvent('onShow');
},
_afterShow: function () {
var me = this;
Lobibox.counter++;
me.$el.attr('data-nth', Lobibox.counter);
if (!me.$options.draggable){
$(window).on('resize.lobibox-'+me.$el.attr('data-nth'), function(){
me.refreshWidth();
me.refreshHeight();
me.$el.css('left', '50%').css('margin-left', '-'+(me.$el.width()/2)+'px');
me.$el.css('top', '50%').css('margin-top', '-'+(me.$el.height()/2)+'px');
});
}
me._triggerEvent('shown');
},
_beforeClose: function () {
var me = this;
me._triggerEvent('beforeClose');
},
_afterClose: function () {
var me = this;
if (!me.$options.draggable){
$(window).off('resize.lobibox-'+me.$el.attr('data-nth'));
}
me._triggerEvent('closed');
},
//------------------------------------------------------------------------------
//--------------------------PUBLIC METHODS--------------------------------------
//------------------------------------------------------------------------------
/**
* Hide the messagebox
*
* @returns {LobiboxBase}
*/
hide: function () {
var me = this;
if (me.$options.hideClass) {
me.$el.removeClass(me.$options.showClass);
me.$el.addClass(me.$options.hideClass);
setTimeout(function () {
callback();
}, me.$options.delayToRemove);
} else {
callback();
}
function callback() {
me.$el.addClass('lobibox-hidden');
if ($('.lobibox[data-is-modal=true]:not(.lobibox-hidden)').length === 0) {
$('.lobibox-backdrop').remove();
$('body').removeClass(Lobibox.base.OPTIONS.bodyClass);
}
}
return this;
},
/**
* Removes the messagebox from document
*
* @returns {LobiboxBase}
*/
destroy: function () {
var me = this;
me._beforeClose();
if (me.$options.hideClass) {
me.$el.removeClass(me.$options.showClass).addClass(me.$options.hideClass);
setTimeout(function () {
callback();
}, me.$options.delayToRemove);
} else {
callback();
}
function callback() {
me.$el.remove();
if ($('.lobibox[data-is-modal=true]').length === 0) {
$('.lobibox-backdrop').remove();
$('body').removeClass(Lobibox.base.OPTIONS.bodyClass);
}
me._afterClose();
}
return this;
},
/**
* Set the width of messagebox
*
* @param {number} width "new width of messagebox"
* @returns {LobiboxBase}
*/
setWidth: function (width) {
var me = this;
me.$el.css('width', me._calculateWidth(width));
return me;
},
refreshWidth: function(){
this.setWidth(this.$el.width());
},
refreshHeight: function(){
this.setHeight(this.$el.height());
},
/**
* Set the height of messagebox
*
* @param {number} height "new height of messagebox"
* @returns {LobiboxBase}
*/
setHeight: function (height) {
var me = this;
me.$el.css('height', me._calculateHeight(height))
.find('.lobibox-body')
.css('height', me._calculateBodyHeight(me.$el.innerHeight()));
return me;
},
/**
* Set the width and height of messagebox
*
* @param {number} width "new width of messagebox"
* @param {number} height "new height of messagebox"
* @returns {LobiboxBase}
*/
setSize: function (width, height) {
var me = this;
me.setWidth(width);
me.setHeight(height);
return me;
},
/**
* Set position of messagebox
*
* @param {number|String} left "left coordinate of messsagebox or string representaing position. Available: ('top', 'center', 'bottom')"
* @param {number} top
* @returns {LobiboxBase}
*/
setPosition: function (left, top) {
var pos;
if (typeof left === 'number' && typeof top === 'number') {
pos = {
left: left,
top: top
};
} else if (typeof left === 'string') {
pos = this._calculatePosition(left);
}
this.$el.css(pos);
return this;
},
/**
* Set the title of messagebox
*
* @param {string} title "new title of messagebox"
* @returns {LobiboxBase}
*/
setTitle: function (title) {
return this.$el.find('.lobibox-title').html(title);
},
/**
* Get the title of messagebox
*
* @returns {string}
*/
getTitle: function () {
return this.$el.find('.lobibox-title').html();
},
/**
* Show messagebox
*
* @returns {LobiboxBase}
*/
show: function () {
var me = this,
$body = $('body');
me._beforeShow();
me.$el.removeClass('lobibox-hidden');
$body.append(me.$el);
if (me.$options.buttons) {
var buttons = me.$el.find('.lobibox-footer').children();
buttons[0].focus();
}
if (me.$options.modal) {
$body.addClass(Lobibox.base.OPTIONS.bodyClass);
me._addBackdrop();
}
if (me.$options.delay !== false) {
setTimeout(function () {
me.destroy();
}, me.$options.delay);
}
me._afterShow();
return me;
}
};
//User can set default options by this variable
Lobibox.base = {};
Lobibox.base.OPTIONS = {
bodyClass: 'lobibox-open',
modalClasses: {
'error': 'lobibox-error',
'success': 'lobibox-success',
'info': 'lobibox-info',
'warning': 'lobibox-warning',
'confirm': 'lobibox-confirm',
'progress': 'lobibox-progress',
'prompt': 'lobibox-prompt',
'default': 'lobibox-default',
'window': 'lobibox-window'
},
buttonsAlign: ['left', 'center', 'right'],
buttons: {
ok: {
'class': 'lobibox-btn lobibox-btn-default',
text: 'OK',
closeOnClick: true
},
cancel: {
'class': 'lobibox-btn lobibox-btn-cancel',
text: 'Cancel',
closeOnClick: true
},
yes: {
'class': 'lobibox-btn lobibox-btn-yes',
text: 'Yes',
closeOnClick: true
},
no: {
'class': 'lobibox-btn lobibox-btn-no',
text: 'No',
closeOnClick: true
}
},
icons: {
bootstrap: {
confirm: 'glyphicon glyphicon-question-sign',
success: 'glyphicon glyphicon-ok-sign',
error: 'glyphicon glyphicon-remove-sign',
warning: 'glyphicon glyphicon-exclamation-sign',
info: 'glyphicon glyphicon-info-sign'
},
fontAwesome: {
confirm: 'fa fa-question-circle',
success: 'fa fa-check-circle',
error: 'fa fa-times-circle',
warning: 'fa fa-exclamation-circle',
info: 'fa fa-info-circle'
}
}
};
Lobibox.base.DEFAULTS = {
horizontalOffset: 5, //If the messagebox is larger (in width) than window's width. The messagebox's width is reduced to window width - 2 * horizontalOffset
verticalOffset: 5, //If the messagebox is larger (in height) than window's height. The messagebox's height is reduced to window height - 2 * verticalOffset
width: 600,
height: 'auto', // Height is automatically calculated by width
closeButton: true, // Show close button or not
draggable: false, // Make messagebox draggable
customBtnClass: 'lobibox-btn lobibox-btn-default', // Class for custom buttons
modal: true,
debug: false,
buttonsAlign: 'center', // Position where buttons should be aligned
closeOnEsc: true, // Close messagebox on Esc press
delayToRemove: 200, // Time after which lobibox will be removed after remove call. (This option is for hide animation to finish)
delay: false, // Time to remove lobibox after shown
baseClass: 'animated-super-fast', // Base class to add all messageboxes
showClass: 'zoomIn', // Show animation class
hideClass: 'zoomOut', // Hide animation class
iconSource: 'bootstrap', // "bootstrap" or "fontAwesome" the library which will be used for icons
//events
//When messagebox show is called but before it is actually shown
onShow: null,
//After messagebox is shown
shown: null,
//When messagebox remove method is called but before it is actually hidden
beforeClose: null,
//After messagebox is hidden
closed: null
};
//------------------------------------------------------------------------------
//-------------------------LobiboxPrompt----------------------------------------
//------------------------------------------------------------------------------
function LobiboxPrompt(type, options) {
this.$input = null;
this.$type = 'prompt';
this.$promptType = type;
options = $.extend({}, Lobibox.prompt.DEFAULT_OPTIONS, options);
this.$options = this._processInput(options);
this._init();
this.debug(this);
}
LobiboxPrompt.prototype = $.extend({}, LobiboxBase, {
constructor: LobiboxPrompt,
_processInput: function (options) {
var me = this;
var mergedOptions = LobiboxBase._processInput.call(me, options);
mergedOptions.buttons = {
ok: Lobibox.base.OPTIONS.buttons.ok,
cancel: Lobibox.base.OPTIONS.buttons.cancel
};
options = $.extend({}, mergedOptions, LobiboxPrompt.DEFAULT_OPTIONS, options);
return options;
},
_init: function () {
var me = this;
LobiboxBase._init.call(me);
me.show();
},
_afterShow: function () {
var me = this;
me._setContent(me._createInput())._position();
me.$input.focus();
LobiboxBase._afterShow.call(me);
},
_createInput: function () {
var me = this,
label;
if (me.$options.multiline) {
me.$input = $('<textarea></textarea>').attr('rows', me.$options.lines);
} else {
me.$input = $('<input type="' + me.$promptType + '"/>');
}
me.$input.addClass('lobibox-input').attr(me.$options.attrs);
if (me.$options.value) {
me.setValue(me.$options.value);
}
if (me.$options.label) {
label = $('<label>' + me.$options.label + '</label>');
}
return $('<div></div>').append(label, me.$input);
},
/**
* Set value of input
*
* @param {string} val "value of input"
* @returns {LobiboxPrompt}
*/
setValue: function (val) {
this.$input.val(val);
return this;
},
/**
* Get value of input
*
* @returns {String}
*/
getValue: function () {
return this.$input.val();
},
isValid: function () {
var me = this,
$error = me.$el.find('.lobibox-input-error-message');
if (me.$options.required && !me.getValue()){
me.$input.addClass('invalid');
if ($error.length === 0){
me.$el.find('.lobibox-body').append('<p class="lobibox-input-error-message">'+me.$options.errorMessage+'</p>');
me._position();
me.$input.focus();
}
return false;
}
me.$input.removeClass('invalid');
$error.remove();
me._position();
me.$input.focus();
return true;
}
});
LobiboxPrompt.DEFAULT_OPTIONS = {
width: 400,
attrs: {}, // Object of any valid attribute of input field
value: '', // Value which is given to textfield when messagebox is created
multiline: false, // Set this true for multiline prompt
lines: 3, // This works only for multiline prompt. Number of lines
type: 'text', // Prompt type. Available types (text|number|color)
label: '', // Set some text which will be shown exactly on top of textfield
required: true,
errorMessage: 'The field is required'
};
//------------------------------------------------------------------------------
//-------------------------LobiboxConfirm---------------------------------------
//------------------------------------------------------------------------------
function LobiboxConfirm(options) {
this.$type = 'confirm';
// options = $.extend({}, Lobibox.confirm.DEFAULT_OPTIONS, options);
this.$options = this._processInput(options);
this._init();
this.debug(this);
}
LobiboxConfirm.prototype = $.extend({}, LobiboxBase, {
constructor: LobiboxConfirm,
_processInput: function (options) {
var me = this;
var mergedOptions = LobiboxBase._processInput.call(me, options);
mergedOptions.buttons = {
yes: Lobibox.base.OPTIONS.buttons.yes,
no: Lobibox.base.OPTIONS.buttons.no
};
options = $.extend({}, mergedOptions, Lobibox.confirm.DEFAULTS, options);
return options;
},
_init: function () {
var me = this;
LobiboxBase._init.call(me);
me.show();
},
_afterShow: function () {
var me = this;
var d = $('<div></div>');
if (me.$options.iconClass) {
d.append($('<div class="lobibox-icon-wrapper"></div>')
.append('<i class="lobibox-icon ' + me.$options.iconClass + '"></i>'))
;
}
d.append('<div class="lobibox-body-text-wrapper"><span class="lobibox-body-text">' + me.$options.msg + '</span></div>');
me._setContent(d.html());
me._position();
LobiboxBase._afterShow.call(me);
}
});
Lobibox.confirm.DEFAULTS = {
title: 'Question',
width: 500
};
//------------------------------------------------------------------------------
//-------------------------LobiboxAlert------------------------------------------
//------------------------------------------------------------------------------
function LobiboxAlert(type, options) {
this.$type = type;
// options = $.extend({}, Lobibox.alert.DEFAULT_OPTIONS, Lobibox[type].DEFAULT_OPTIONS, options);
this.$options = this._processInput(options);
this._init();
this.debug(this);
}
LobiboxAlert.prototype = $.extend({}, LobiboxBase, {
constructor: LobiboxAlert,
_processInput: function (options) {
// ALERT_OPTIONS = $.extend({}, LobiboxAlert.OPTIONS, Lobibox.alert.DEFAULTS);
var me = this;
var mergedOptions = LobiboxBase._processInput.call(me, options);
mergedOptions.buttons = {
ok: Lobibox.base.OPTIONS.buttons.ok
};
options = $.extend({}, mergedOptions, Lobibox.alert.OPTIONS[me.$type], Lobibox.alert.DEFAULTS, options);
return options;
},
_init: function () {
var me = this;
LobiboxBase._init.call(me);
me.show();
},
_afterShow: function () {
var me = this;
var d = $('<div></div>');
if (me.$options.iconClass) {
d.append($('<div class="lobibox-icon-wrapper"></div>')
.append('<i class="lobibox-icon ' + me.$options.iconClass + '"></i>'))
;
}
d.append('<div class="lobibox-body-text-wrapper"><span class="lobibox-body-text">' + me.$options.msg + '</span></div>');
me._setContent(d.html());
me._position();
LobiboxBase._afterShow.call(me);
}
});
Lobibox.alert.OPTIONS = {
warning: {
title: 'Warning'
},
info: {
title: 'Information'
},
success: {
title: 'Success'
},
error: {
title: 'Error'
}
};
//User can set default options by this variable
Lobibox.alert.DEFAULTS = {};
//------------------------------------------------------------------------------
//-------------------------LobiboxProgress--------------------------------------
//------------------------------------------------------------------------------
function LobiboxProgress(options) {
this.$type = 'progress';
this.$progressBarElement = null;
this.$options = this._processInput(options);
this.$progress = 0;
this._init();
this.debug(this);
}
LobiboxProgress.prototype = $.extend({}, LobiboxBase, {
constructor: LobiboxProgress,
_processInput: function (options) {
var me = this;
var mergedOptions = LobiboxBase._processInput.call(me, options);
options = $.extend({}, mergedOptions, Lobibox.progress.DEFAULTS, options);
return options;
},
_init: function () {
var me = this;
LobiboxBase._init.call(me);
me.show();
},
_afterShow: function () {
var me = this;
if (me.$options.progressTpl) {
me.$progressBarElement = $(me.$options.progressTpl);
} else {
me.$progressBarElement = me._createProgressbar();
}
var label;
if (me.$options.label) {
label = $('<label>' + me.$options.label + '</label>');
}
var innerHTML = $('<div></div>').append(label, me.$progressBarElement);
me._setContent(innerHTML);
me._position();
LobiboxBase._afterShow.call(me);
},
_createProgressbar: function () {
var me = this;
var outer = $('<div class="lobibox-progress-bar-wrapper lobibox-progress-outer"></div>')
.append('<div class="lobibox-progress-bar lobibox-progress-element"></div>')
;
if (me.$options.showProgressLabel) {
outer.append('<span class="lobibox-progress-text" data-role="progress-text"></span>');
}
return outer;
},
/**
* Set progress value
*
* @param {number} progress "progress value"
* @returns {LobiboxProgress}
*/
setProgress: function (progress) {
var me = this;
if (me.$progress === 100) {
return;
}
progress = Math.min(100, Math.max(0, progress));
me.$progress = progress;
me._triggerEvent('progressUpdated');
if (me.$progress === 100) {
me._triggerEvent('progressCompleted');
}
me.$el.find('.lobibox-progress-element').css('width', progress.toFixed(1) + "%");
me.$el.find('[data-role="progress-text"]').html(progress.toFixed(1) + "%");
return me;
},
/**
* Get progress value
*
* @returns {number}
*/
getProgress: function () {
return this.$progress;
}
});
Lobibox.progress.DEFAULTS = {
width: 500,
showProgressLabel: true, // Show percentage of progress
label: '', // Show progress label
progressTpl: false, //Template of progress bar
//Events
progressUpdated: null,
progressCompleted: null
};
//------------------------------------------------------------------------------
//-------------------------LobiboxWindow----------------------------------------
//------------------------------------------------------------------------------
function LobiboxWindow(type, options) {
this.$type = type;
this.$options = this._processInput(options);
this._init();
this.debug(this);
}
LobiboxWindow.prototype = $.extend({}, LobiboxBase, {
constructor: LobiboxWindow,
_processInput: function (options) {
var me = this;
var mergedOptions = LobiboxBase._processInput.call(me, options);
if (options.content && typeof options.content === 'function') {
options.content = options.content();
}
if (options.content instanceof jQuery) {
options.content = options.content.clone();
}
options = $.extend({}, mergedOptions, Lobibox.window.DEFAULTS, options);
return options;
},
_init: function () {
var me = this;
LobiboxBase._init.call(me);
me.setContent(me.$options.content);
if (me.$options.url && me.$options.autoload) {
if (!me.$options.showAfterLoad) {
me.show();
}
me.load(function () {
if (me.$options.showAfterLoad) {
me.show();
}
});
} else {
me.show();
}
},
_afterShow: function () {
var me = this;
me._position();
LobiboxBase._afterShow.call(me);
},
/**
* Setter method for <code>params</code> option
*
* @param {object} params "new params"
* @returns {LobiboxWindow}
*/
setParams: function (params) {
var me = this;
me.$options.params = params;
return me;
},
/**
* Getter method for <code>params</code>
*
* @returns {object}
*/
getParams: function () {
var me = this;
return me.$options.params;
},
/**
* Setter method of <code>loadMethod</code> option
*
* @param {string} method "new method"
* @returns {LobiboxWindow}
*/
setLoadMethod: function (method) {
var me = this;
me.$options.loadMethod = method;
return me;
},
/**
* Getter method for <code>loadMethod</code> option
*
* @returns {string}
*/
getLoadMethod: function () {
var me = this;
return me.$options.loadMethod;
},
/**
* Setter method of <code>content</code> option.
* Change the content of window
*
* @param {string} content "new content"
* @returns {LobiboxWindow}
*/
setContent: function (content) {
var me = this;
me.$options.content = content;
me.$el.find('.lobibox-body').html('').append(content);
return me;
},
/**
* Getter method of <code>content</code> option
*
* @returns {string}
*/
getContent: function () {
var me = this;
return me.$options.content;
},
/**
* Setter method of <code>url</code> option
*
* @param {string} url "new url"
* @returns {LobiboxWindow}
*/
setUrl: function (url) {
this.$options.url = url;
return this;
},
/**
* Getter method of <code>url</code> option
*
* @returns {String}
*/
getUrl: function () {
return this.$options.url;
},
/**
* Loads content to window by ajax from specific url
*
* @param {Function} callback "callback function"
* @returns {LobiboxWindow}
*/
load: function (callback) {
var me = this;
if (!me.$options.url) {
return me;
}
$.ajax(me.$options.url, {
method: me.$options.loadMethod,
data: me.$options.params
}).done(function (res) {
me.setContent(res);
if (callback && typeof callback === 'function') {
callback(res);
}
});
return me;
}
});
Lobibox.window.DEFAULTS = {
width: 480,
height: 600,
content: '', // HTML Content of window
url: '', // URL which will be used to load content
draggable: true, // Override default option
autoload: true, // Auto load from given url when window is created
loadMethod: 'GET', // Ajax method to load content
showAfterLoad: true, // Show window after content is loaded or show and then load content
params: {} // Parameters which will be send by ajax for loading content
};
})();
//Author : @arboshiki
/**
* Generates random string of n length.
* String contains only letters and numbers
*
* @param {int} n
* @returns {String}
*/
Math.randomString = function (n) {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < n; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
};
var Lobibox = Lobibox || {};
(function () {
var LobiboxNotify = function (type, options) {
//------------------------------------------------------------------------------
//----------------PROTOTYPE VARIABLES-------------------------------------------
//------------------------------------------------------------------------------
this.$type = null;
this.$options = null;
this.$el = null;
//------------------------------------------------------------------------------
//-----------------PRIVATE VARIABLES--------------------------------------------
//------------------------------------------------------------------------------
var me = this;
//------------------------------------------------------------------------------
//-----------------PRIVATE FUNCTIONS--------------------------------------------
//------------------------------------------------------------------------------
var _processInput = function (options) {
if (options.size === 'mini' || options.size === 'large') {
options = $.extend({}, Lobibox.notify.OPTIONS[options.size], options);
}
options = $.extend({}, Lobibox.notify.OPTIONS[me.$type], Lobibox.notify.DEFAULTS, options);
if (options.size !== 'mini' && options.title === true) {
options.title = Lobibox.notify.OPTIONS[me.$type].title;
} else if (options.size === 'mini' && options.title === true) {
options.title = false;
}
if (options.icon === true) {
options.icon = Lobibox.notify.OPTIONS.icons[options.iconSource][me.$type];
}
if (options.sound === true) {
options.sound = Lobibox.notify.OPTIONS[me.$type].sound;
}
if (options.sound) {
options.sound = options.soundPath + options.sound + options.soundExt;
}
return options;
};
var _appendInWrapper = function ($el, $wrapper) {
if (me.$options.size === 'normal') {
if ($wrapper.hasClass('bottom')) {
$wrapper.prepend($el);
} else {
$wrapper.append($el);
}
} else if (me.$options.size === 'mini') {
if ($wrapper.hasClass('bottom')) {
$wrapper.prepend($el);
} else {
$wrapper.append($el);
}
} else if (me.$options.size === 'large') {
var tabPane = _createTabPane().append($el);
var $li = _createTabControl(tabPane.attr('id'));
$wrapper.find('.lb-notify-wrapper').append(tabPane);
$wrapper.find('.lb-notify-tabs').append($li);
_activateTab($li);
$li.find('>a').click(function () {
_activateTab($li);
});
}
};
var _activateTab = function ($li) {
$li.closest('.lb-notify-tabs').find('>li').removeClass('active');
$li.addClass('active');
var $current = $($li.find('>a').attr('href'));
$current.closest('.lb-notify-wrapper').find('>.lb-tab-pane').removeClass('active');
$current.addClass('active')
};
var _createTabControl = function (tabPaneId) {
var $li = $('<li></li>', {
'class': Lobibox.notify.OPTIONS[me.$type]['class']
});
$('<a></a>', {
'href': '#' + tabPaneId
}).append('<i class="tab-control-icon ' + me.$options.icon + '"></i>')
.appendTo($li);
return $li;
};
var _createTabPane = function () {
return $('<div></div>', {
'class': 'lb-tab-pane',
'id': Math.randomString(10)
})
};
var _createNotifyWrapper = function () {
var selector = (me.$options.size === 'large' ? '.lobibox-notify-wrapper-large' : '.lobibox-notify-wrapper')
+ "." + me.$options.position.replace(/\s/gi, '.'),
$wrapper;
//var classes = me.$options.position.split(" ");
$wrapper = $(selector);
if ($wrapper.length === 0) {
$wrapper = $('<div></div>')
.addClass(selector.replace(/\./g, ' ').trim())
.appendTo($('body'));
if (me.$options.size === 'large') {
$wrapper.append($('<ul class="lb-notify-tabs"></ul>'))
.append($('<div class="lb-notify-wrapper"></div>'));
}
}
return $wrapper;
};
var _createNotify = function () {
var OPTS = Lobibox.notify.OPTIONS,
$iconEl,
$innerIconEl,
$iconWrapper,
$body,
$msg,
$notify = $('<div></div>', {
'class': 'lobibox-notify ' + OPTS[me.$type]['class'] + ' ' + OPTS['class'] + ' ' + me.$options.showClass
});
$iconWrapper = $('<div class="lobibox-notify-icon-wrapper"></div>').appendTo($notify);
$iconEl = $('<div class="lobibox-notify-icon"></div>').appendTo($iconWrapper);
$innerIconEl = $('<div></div>').appendTo($iconEl);
// Add image or icon depending on given parameters
if (me.$options.img) {
$innerIconEl.append('<img src="' + me.$options.img + '"/>');
} else if (me.$options.icon) {
$innerIconEl.append('<div class="icon-el"><i class="' + me.$options.icon + '"></i></div>');
} else {
$notify.addClass('without-icon');
}
// Create body, append title and message in body and append body in notification
$msg = $('<div class="lobibox-notify-msg">' + me.$options.msg + '</div>');
if (me.$options.messageHeight !== false) {
$msg.css('max-height', me.$options.messageHeight);
}
$body = $('<div></div>', {
'class': 'lobibox-notify-body'
}).append($msg).appendTo($notify);
if (me.$options.title) {
$body.prepend('<div class="lobibox-notify-title">' + me.$options.title + '<div>');
}
_addCloseButton($notify);
if (me.$options.size === 'normal' || me.$options.size === 'mini') {
_addCloseOnClick($notify);
_addDelay($notify);
}
// Give width to notification
if (me.$options.width) {
$notify.css('width', _calculateWidth(me.$options.width));
}
return $notify;
};
var _addCloseButton = function ($el) {
if (!me.$options.closable) {
return;
}
$('<span class="lobibox-close">&times;</span>')
.click(function (ev) {
ev.preventDefault();
ev.stopPropagation();
me.remove();
}).appendTo($el);
};
var _addCloseOnClick = function ($el) {
if (!me.$options.closeOnClick) {
return;
}
$el.click(function () {
me.remove();
});
};
var _addDelay = function ($el) {
if (!me.$options.delay) {
return;
}
if (me.$options.delayIndicator) {
var delay = $('<div class="lobibox-delay-indicator"><div></div></div>');
$el.append(delay);
}
var time = 0;
var interval = 1000 / 30;
var currentTime = new Date().getTime();
var timer = setInterval(function () {
if (me.$options.continueDelayOnInactiveTab) {
time = new Date().getTime() - currentTime;
} else {
time += interval;
}
var width = 100 * time / me.$options.delay;
if (width >= 100) {
width = 100;
me.remove();
timer = clearInterval(timer);
}
if (me.$options.delayIndicator) {
delay.find('div').css('width', width + "%");
}
}, interval);
if (me.$options.pauseDelayOnHover) {
$el.on('mouseenter.lobibox', function () {
interval = 0;
}).on('mouseleave.lobibox', function () {
interval = 1000 / 30;
});
}
};
var _findTabToActivate = function ($li) {
var $itemToActivate = $li.prev();
if ($itemToActivate.length === 0) {
$itemToActivate = $li.next();
}
if ($itemToActivate.length === 0) {
return null;
}
return $itemToActivate;
};
var _calculateWidth = function (width) {
width = Math.min($(window).outerWidth(), width);
return width;
};
//------------------------------------------------------------------------------
//----------------PROTOTYPE FUNCTIONS-------------------------------------------
//------------------------------------------------------------------------------
/**
* Delete the notification
*
* @returns {LobiboxNotify}
*/
this.remove = function () {
me.$el.removeClass(me.$options.showClass)
.addClass(me.$options.hideClass);
var parent = me.$el.parent();
var wrapper = parent.closest('.lobibox-notify-wrapper-large');
var href = '#' + parent.attr('id');
var $li = wrapper.find('>.lb-notify-tabs>li:has(a[href="' + href + '"])');
$li.addClass(Lobibox.notify.OPTIONS['class'])
.addClass(me.$options.hideClass);
setTimeout(function () {
if (me.$options.size === 'normal' || me.$options.size === 'mini') {
me.$el.remove();
} else if (me.$options.size === 'large') {
var $newLi = _findTabToActivate($li);
if ($newLi) {
_activateTab($newLi);
}
$li.remove();
parent.remove();
}
var list = Lobibox.notify.list;
var ind = list.indexOf(me);
list.splice(ind, 1);
var next = list[ind];
if (next && next.$options.showAfterPrevious) {
next._init();
}
}, 500);
return me;
};
me._init = function () {
// Create notification
var $notify = _createNotify();
if (me.$options.size === 'mini') {
$notify.addClass('notify-mini');
}
if (typeof me.$options.position === 'string') {
var $wrapper = _createNotifyWrapper();
_appendInWrapper($notify, $wrapper);
if ($wrapper.hasClass('center')) {
$wrapper.css('margin-left', '-' + ($wrapper.width() / 2) + "px");
}
} else {
$('body').append($notify);
$notify.css({
'position': 'fixed',
left: me.$options.position.left,
top: me.$options.position.top
})
}
me.$el = $notify;
if (me.$options.sound) {
var snd = new Audio(me.$options.sound); // buffers automatically when created
snd.play();
}
if (me.$options.rounded) {
me.$el.addClass('rounded');
}
me.$el.on('click.lobibox', function (ev) {
if (me.$options.onClickUrl) {
window.location.href = me.$options.onClickUrl;
}
if (me.$options.onClick && typeof me.$options.onClick === 'function') {
me.$options.onClick.call(me, ev);
}
});
me.$el.data('lobibox', me);
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
this.$type = type;
this.$options = _processInput(options);
if (!me.$options.showAfterPrevious || Lobibox.notify.list.length === 0) {
this._init();
}
};
Lobibox.notify = function (type, options) {
if (["default", "info", "warning", "error", "success"].indexOf(type) > -1) {
var lobibox = new LobiboxNotify(type, options);
Lobibox.notify.list.push(lobibox);
return lobibox;
}
};
Lobibox.notify.list = [];
Lobibox.notify.closeAll = function () {
var list = Lobibox.notify.list;
for (var i in list) {
list[i].remove();
}
};
//User can set default options to this variable
Lobibox.notify.DEFAULTS = {
title: true, // Title of notification. If you do not include the title in options it will automatically takes its value
//from Lobibox.notify.OPTIONS object depending of the type of the notifications or set custom string. Set this false to disable title
size: 'normal', // normal, mini, large
soundPath: 'sounds/', // The folder path where sounds are located
soundExt: '.ogg', // Default extension for all sounds
showClass: 'fadeInDown', // Show animation class.
hideClass: 'zoomOut', // Hide animation class.
icon: true, // Icon of notification. Leave as is for default icon or set custom string
msg: '', // Message of notification
img: null, // Image source string
closable: true, // Make notifications closable
hideCloseButton: false, // Notification may be closable but you can hide close button and it will be closed by clicking on notification itsef
delay: 5000, // Hide notification after this time (in miliseconds)
delayIndicator: true, // Show timer indicator
closeOnClick: true, // Close notifications by clicking on them
width: 400, // Width of notification box
sound: true, // Sound of notification. Set this false to disable sound. Leave as is for default sound or set custom soud path
// Place to show notification. Available options: "top left", "top right", "bottom left", "bottom right", "center top", "center bottom"
// It can also be object {left: number, top: number} to position notification at any place
position: "bottom right",
iconSource: 'bootstrap', // "bootstrap" or "fontAwesome" the library which will be used for icons
rounded: false, // Whether to make notification corners rounded
messageHeight: 60, // Notification message maximum height. This is not for notification itself, this is for <code>.lobibox-notify-msg</code>
pauseDelayOnHover: true, // When you mouse over on notification delay (if it is enabled) will be paused.
onClickUrl: null, // The url which will be opened when notification is clicked
showAfterPrevious: false, // Set this to true if you want notification not to be shown until previous notification is closed. This is useful for notification queues
continueDelayOnInactiveTab: true, // Continue delay when browser tab is inactive
// Events
onClick: null
};
//This variable is necessary.
Lobibox.notify.OPTIONS = {
'class': 'animated-fast',
large: {
width: 500,
messageHeight: 96
},
mini: {
'class': 'notify-mini',
messageHeight: 32
},
default: {
'class': 'lobibox-notify-default',
'title': 'Default',
sound: false
},
success: {
'class': 'lobibox-notify-success',
'title': 'Success',
sound: 'sound2'
},
error: {
'class': 'lobibox-notify-error',
'title': 'Error',
sound: 'sound4'
},
warning: {
'class': 'lobibox-notify-warning',
'title': 'Warning',
sound: 'sound5'
},
info: {
'class': 'lobibox-notify-info',
'title': 'Information',
sound: 'sound6'
},
icons: {
bootstrap: {
success: 'glyphicon glyphicon-ok-sign',
error: 'glyphicon glyphicon-remove-sign',
warning: 'glyphicon glyphicon-exclamation-sign',
info: 'glyphicon glyphicon-info-sign'
},
fontAwesome: {
success: 'fa fa-check-circle',
error: 'fa fa-times-circle',
warning: 'fa fa-exclamation-circle',
info: 'fa fa-info-circle'
}
}
};
})();