diff --git a/pandora_console/include/javascript/fixed-bottom-box.js b/pandora_console/include/javascript/fixed-bottom-box.js new file mode 100644 index 0000000000..98ac15a029 --- /dev/null +++ b/pandora_console/include/javascript/fixed-bottom-box.js @@ -0,0 +1,351 @@ +/** + * File: fixed-bottom-box.js + * Name: fixedBottomBox + * Dependencies: jQuery + */ + +// This module has an Universal Module Definition pattern and its scope is private + +(function (name, factory) { + // AMD + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } + // Node (CommonJS) + else if (typeof exports === 'object') { + module.exports = factory(require('jquery')); + } + // Assign to the jQuery namespace + else { + (this.jQuery || this.$)[name] = factory(this.jQuery || this.$); + } +} ('fixedBottomBox', function ($) { + // jQuery required + if (typeof $ === 'undefined') + return; + // Module definition + return fixedBottomBox = function (params) { + var self = new Object(); + + self._rendered = false; + + self.isRendered = function (state) { + if (typeof state === 'boolean') + self._rendered = state; + + return self._rendered; + } + + params = params || {}; + self._debug = params.debug || false; + self._target = params.target || 'body'; + self._opened = params.opened || false; + self._head = params.head || ''; + self._content = params.content || ''; + self._animationDuration = params.animationDuration || 200; + + self._width = params.width || 300; + self._height = params.height || 400; + + self.setWidth = function (width) { + if (typeof width !== 'number' || width <= 0) + throw new TypeError('Invalid width'); + self._width = width; + + if (typeof self._box !== 'undefined') { + self._box.head.css('width', width + 'px'); + self._box.content.css('width', width + 'px'); + } + + return self; + } + + self.getWidth = function (width) { + return self._width; + } + + self.setHeight = function (height) { + if (typeof height !== 'number' || height <= 0) + throw new TypeError('Invalid height'); + self._heigth = height; + + var headHeight = self._box.head.height() || 30; + + if (typeof self._box !== 'undefined') { + self._box.content.css('max-height', (height - headHeight) + 'px'); + } + + return self; + } + + self.getHeight = function (height) { + return self._height; + } + + self.resize = function (width, height) { + try { + self.setWidth(width); + self.setHeight(height); + self.emit('resized', { width: width, height: height }); + } + catch (error) { + if (self._debug) + console.error(error); + } + + return self; + } + + self.render = function (head, content) { + self._createBox(head, content); + + return self; + } + + self._renderHead = function (head) { + head = head || self._head; + + var headBody = $('
'); + headBody + .addClass('fixed-bottom-box-head-body') + .append(head) + .click(function(event) { + self.toggle(); + }); + var headClose = $(''); + headClose + .addClass('fixed-bottom-box-head-close') + .click(function(event) { + self.close(); + }); + + self._box.head = $('
'); + self._box.head + .addClass('fixed-bottom-box-head') + .append(headClose, headBody); + self._box.append(self._box.head); + + self.emit('head-rendered', { headRef: self._box.head, headContent: head }); + } + + self._renderContent = function (content) { + content = content || self._content; + + self._box.content = $('
'); + self._box.content + .addClass('fixed-bottom-box-content') + .append(content); + self._box.append(self._box.content); + + self.emit('content-rendered', { contentRef: self._box.content, content: content }); + } + + self._createBox = function (head, content) { + head = head || self._head; + content = content || self._content; + + if (self.isRendered()) + self._destroyBox(); + + try { + self._box = $('
'); + self._box + .addClass('fixed-bottom-box') + .css('position', 'fixed') + .css('bottom', '0px') + .css('right', '20px'); + + self._renderHead(head); + self._renderContent(content); + + self.resize(self._width, self._height); + + if (!self.isOpen()) + self._box.content.hide(); + + $(self._target).append(self._box); + + self.isRendered(true); + + self.emit('rendered', { boxRef: self._box, headContent: head, content: content }); + } + catch (error) { + if (self._debug) + console.error(error); + } + } + + self._destroyBox = function () { + try { + if (self.isRendered()) { + self._box.hide(); + + self._box.content.remove(); + delete self._box.content; + + self._box.head.remove(); + delete self._box.head; + + self._box.remove(); + delete self._box; + + self.isRendered(false); + } + } + catch (error) { + if (self._debug) + console.error(error); + } + } + + + self.isOpen = function (state) { + if (typeof state === 'boolean') + self._opened = state; + + return self._opened; + } + + self.setHead = function (head) { + if (typeof head === 'undefined' || head.length <= 0) + throw new TypeError('Invalid head'); + self._head = head; + + return self; + } + + self.setContent = function (content) { + if (typeof content === 'undefined' || content.length <= 0) + throw new TypeError('Invalid content'); + self._content = content; + + return self; + } + + self.open = function () { + try { + if (!self.isOpen()) { + self._box.content.slideDown(self._animationDuration, function() { + self.isOpen(true); + $(this) + .removeClass('fixed-bottom-box-hided') + .addClass('fixed-bottom-box-opened'); + self.emit('open', { ref: self }); + }); + } + } + catch (error) { + if (self._debug) + console.error(error); + } + } + + self.hide = function () { + try { + if (self.isOpen()) { + + self._box.content.slideUp(self._animationDuration, function() { + self.isOpen(false); + $(this) + .removeClass('fixed-bottom-box-opened') + .addClass('fixed-bottom-box-hided'); + self.emit('hide', { ref: self }); + }); + } + } + catch (error) { + if (self._debug) + console.error(error); + } + } + + self.toggle = function () { + if (self.isOpen()) + self.hide(); + else + self.open(); + } + + self.close = function () { + try { + self._head = ''; + self._content = ''; + self.isOpen(false); + self._destroyBox(); + + self.emit('close', {}); + } + catch (error) { + if (self._debug) + console.error(error); + } + } + + + //-- Event handlers --// + + // Populate the observers + var eventsList = ['open', 'hide', 'close', 'rendered', 'head-rendered', 'content-rendered', 'resized']; + self._observers = {} + eventsList.forEach(function(eventName) { + self._observers[eventName] = []; + }); + + self.emit = function (eventName, payload) { + if (typeof eventName === 'undefined' || eventName.length <= 0) + throw new TypeError('Invalid event name'); + if (typeof self._observers[eventName] === 'undefined') + throw new TypeError('The introduced event does not exists'); + payload = payload || {}; + + var observers = self._observers[eventName]; + + observers.forEach(function(callback) { + if (typeof callback === 'function') + callback(payload); + }); + } + + self.on = function (eventName, callback) { + if (typeof eventName === 'undefined' || eventName.length <= 0) + throw new TypeError('Invalid event name'); + if (typeof callback === 'function') + throw new TypeError('The callback should be a function'); + + var res = false; + if (typeof self._observers[eventName] !== 'undefined') { + var length = self._observers[eventName].push(callback); + res = length - 1; + } + + return res; + } + + // Should receive + self.onOpen = function (callback) { + self.on('open', callback); + } + // Should receive + self.onHide = function (callback) { + self.on('hide', callback); + } + // Should receive + self.onClose = function (callback) { + self.on('close', callback); + } + // Should receive + self.onHeadRender = function (callback) { + self.on('head-rendered', callback); + } + // Should receive + self.onContentRender = function (callback) { + self.on('content-rendered', callback); + } + // Should receive + self.onResize = function (callback) { + self.on('resized', callback); + } + + return self; + } +})); \ No newline at end of file diff --git a/pandora_console/include/styles/fixed-bottom-box.css b/pandora_console/include/styles/fixed-bottom-box.css new file mode 100644 index 0000000000..8a3e7de7aa --- /dev/null +++ b/pandora_console/include/styles/fixed-bottom-box.css @@ -0,0 +1,98 @@ +div.fixed-bottom-box { + background: #E1E1E1; + + border-radius: 10px 10px 0 0; + -moz-border-radius: 10px 10px 0 0; + -webkit-border-radius: 10px 10px 0 0; + -o-border-radius: 10px 10px 0 0; + -ms-border-radius: 10px 10px 0 0; + -khtml-border-radius: 10px 10px 0 0; +} + +div.fixed-bottom-box > +div.fixed-bottom-box-head { + height: 30px; + line-height: 30px; + vertical-align: middle; + background-color: #3F3F3F; + + border-radius: 10px 10px 0 0; + -moz-border-radius: 10px 10px 0 0; + -webkit-border-radius: 10px 10px 0 0; + -o-border-radius: 10px 10px 0 0; + -ms-border-radius: 10px 10px 0 0; + -khtml-border-radius: 10px 10px 0 0; +} + +div.fixed-bottom-box > +div.fixed-bottom-box-head > +div.fixed-bottom-box-head-body { + height: inherit; + line-height: inherit; + color: #FFFFFF; + font-weight: bold; + vertical-align: middle; + text-align: center; +} + +div.fixed-bottom-box > +div.fixed-bottom-box-head > +span.fixed-bottom-box-head-close { + height: 30px; + width: 30px; + background-image: url(../../images/input_cross.png); + background-repeat: no-repeat; + background-position: center; + float: right; +} + +div.fixed-bottom-box > +div.fixed-bottom-box-head > +div.fixed-bottom-box-head-body:hover { + cursor: pointer; + background-color: #747474; + + border-radius: inherit; + -moz-border-radius: inherit; + -webkit-border-radius: inherit; + -o-border-radius: inherit; + -ms-border-radius: inherit; + -khtml-border-radius: inherit; +} + +div.fixed-bottom-box > +div.fixed-bottom-box-head > +span.fixed-bottom-box-head-close:hover { + cursor: pointer; + background-color: #747474; + + border-radius: 0 10px 0 0; + -moz-border-radius: 0 10px 0 0; + -webkit-border-radius: 0 10px 0 0; + -o-border-radius: 0 10px 0 0; + -ms-border-radius: 0 10px 0 0; + -khtml-border-radius: 0 10px 0 0; +} + +div.fixed-bottom-box.fixed-bottom-box-hided > +div.fixed-bottom-box-head > +div.fixed-bottom-box-head-body { + /*background-image: url(../../images/.png); + background-repeat: no-repeat; + background-position: right;*/ +} + +div.fixed-bottom-box.fixed-bottom-box-opened > +div.fixed-bottom-box-head > +div.fixed-bottom-box-head-body { + /*background-image: url(../../images/.png); + background-repeat: no-repeat; + background-position: right;*/ +} + +div.fixed-bottom-box > +div.fixed-bottom-box-content { + vertical-align: top; + text-align: center; + overflow: auto; +} diff --git a/pandora_console/include/styles/pandora.css b/pandora_console/include/styles/pandora.css index 5cfc2f704f..11a79de117 100644 --- a/pandora_console/include/styles/pandora.css +++ b/pandora_console/include/styles/pandora.css @@ -23,6 +23,7 @@ Description: The default Pandora FMS theme layout /* Tree view styles */ @import url(tree.css); +@import url(fixed-bottom-box.css); * { font-family: verdana, sans-serif;