├── LICENSE ├── README.md ├── bower.json ├── demo ├── index.html └── reload.php ├── package.json └── widgster.js /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 flatlogic.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Widgster 2 | ====================== 3 | 4 | Small jQuery plugin that provides an easy way to handle basic widget functions like collapsing, closing, ajax-refreshing & fullsreening. 5 | 6 | **[Demo](http://widgster.flatlogic.com/demo/index.html)** 7 | 8 | **[Advanced Demo](http://demo.flatlogic.com/4.0.1/dark/grid_live.html)** 9 | 10 | Use 11 | ------------ 12 | 13 | 14 | To apply all these features to your default widget you have to add appropriate links (or buttons) to it: 15 | 16 |
17 |
18 |

Header

19 |
20 | Reload 21 | Expand 22 | Collapse 23 | Fullscreen 24 | Restore 25 | Close 26 |
27 |
28 |
29 | Body 30 |
31 |
32 | 33 | In the example above links are put into a `.widget-controls` but you can put them anywhere inside of widget. 34 | 35 | Then widgster needs to be initialized via javascript: 36 | 37 | $('.widget').widgster(); 38 | 39 | As you could guess `data-widgster` attribute defines widget action to be performed when link is clicked. 40 | 41 | Actions 42 | ------------ 43 | 44 | * **close** - closes the widget; 45 | * **collapse** - collapses (minimizes) the widget. An element holding this data attribute will be hidden when widget gets expanded; 46 | * **expand** - expands the widget. An element holding this data attribute will be hidden when widget gets collapsed; 47 | * **fullscreen** - fullscreens the widget. An element holding this data attribute will be hidden when widget gets restored; 48 | * **restore** - restores the widget back to its position. An element holding this data attribute will be hidden when widget gets fullscreened; 49 | * **load** - reloads widget content from the url provided with `data-widget-load` attribute. 50 | 51 | All actions may be called via js: 52 | 53 | $('.widget').widgster('close'); 54 | 55 | Options 56 | ------------ 57 | 58 | * **collapsed** - if true collapses widget after page load; 59 | * **fullscreened** - if true fullscreens widget after page load; 60 | * **bodySelector** - widget body selector. Used for loading and collapsing. Default is `.body`; 61 | * **load** - an url to fetch widget body from. Default is `undefined`; 62 | * **showLoader** - whether to show a loader when ajax refresh performed. Default is `true`; 63 | * **autoload** - whether to automatically perform ajax refresh after page load. May be set to an integer value. If set, for example, to 2000 will refresh the widget every 2 seconds. Default is `false`; 64 | * **closePrompt(callback)** - a function to be called when closing. Closing is only performed when `callback` is called. 65 | 66 | Widgster accepts an object with options: 67 | 68 | $('.widget').widgster({ 69 | collapsed: true 70 | }); 71 | 72 | Events 73 | ------------ 74 | 75 | Each action fires both before and after event. Events have the same names as actions. Before event may be canceled. 76 | 77 | For example, to make refresh button spin: 78 | 79 | $('.widget').on("load.widgster", function(){ 80 | $(this).find('[data-widgster="load"] > i').addClass('fa-spin') 81 | }).on("loaded.widgster", function(){ 82 | $(this).find('[data-widgster="load"] > i').removeClass('fa-spin') 83 | }); 84 | 85 | How can I support the developers? 86 | ------------------------------------ 87 | - Star our GitHub repo :star: 88 | - Create pull requests, submit bugs, suggest new features or documentation updates :wrench: 89 | - Follow us on [Twitter](https://twitter.com/flatlogic) :feet: 90 | - Like our page on [Facebook](https://www.facebook.com/flatlogic/) :thumbsup: 91 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "widgster", 3 | "main": "widgster.js", 4 | "version": "0.0.3", 5 | "homepage": "https://github.com/okendoken/widgster", 6 | "authors": [ 7 | "okendoken (http://flatlogic.com)" 8 | ], 9 | "license": "MIT", 10 | "ignore": [ 11 | "**/.*", 12 | "node_modules", 13 | "bower_components", 14 | "test", 15 | "tests" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 26 | 27 |
28 |
29 |
30 |

Header

31 |
32 | Reload 33 | Expand 34 | Collapse 35 | Fullscreen 36 | Restore 37 | Close 38 |
39 |
40 |
41 |

Yes, I am widget body. I may contain lots of cool stuff like lore ipsum, etc.

42 |

But!

43 |

This time I am going to show you something really cool. I will be just body and that's it. 44 | Can you imagine that?

45 |
46 |
47 |
48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /demo/reload.php: -------------------------------------------------------------------------------- 1 | 2 |

Yes, I was reloaded at , and yes, I am widget body. I may contain lots of cool stuff like lore ipsum, etc.

3 |

But!

4 |

This time I am going to show you something really cool. I will be just body and that's it. 5 | Can you imagine that?

-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "widgster", 3 | "version": "1.0.0", 4 | "description": "jQuery plugin that provides an easy way to handle basic widget functions like collapsing, closing, ajax-refreshing & fullsreening", 5 | "main": "widgster.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/flatlogic/widgster.git" 12 | }, 13 | "keywords": [ 14 | "jquery", 15 | "widget" 16 | ], 17 | "author": "https://flatlogic.com", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/flatlogic/widgster/issues" 21 | }, 22 | "homepage": "https://github.com/flatlogic/widgster#readme" 23 | } 24 | -------------------------------------------------------------------------------- /widgster.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Widgster plugin. 3 | */ 4 | ( function( global, factory ) { 5 | "use strict"; 6 | 7 | if (global.jQuery && global.jQuery.fn) { 8 | factory(global.jQuery); 9 | } else { 10 | console.warn("Widgster must be executed in a browser environment with jQuery defined"); 11 | } 12 | } )( typeof window !== "undefined" ? window : this, function( $ ) { 13 | // WIDGSTER CLASS DEFINITION 14 | // ====================== 15 | 16 | var Widgster = function (el, options) { 17 | this.$element = $(el); 18 | this.$collapse = this.$element.find('[data-widgster=collapse]'); 19 | this.$expand = this.$element.find('[data-widgster=expand]'); 20 | this.$fullscreen = this.$element.find('[data-widgster=fullscreen]'); 21 | this.$restore = this.$element.find('[data-widgster=restore]'); 22 | this.options = options; 23 | this.collapsed = options.collapsed; 24 | this.fullscreened = options.fullscreened; 25 | 26 | this._initHandlers(); 27 | 28 | if (this.collapsed){ 29 | this.collapse(false); 30 | } else { 31 | this.$expand.hide(); 32 | } 33 | 34 | if (this.fullscreened){ 35 | this.fullscreen(); 36 | } else { 37 | this.$restore.hide(); 38 | } 39 | 40 | this.options.autoload && this.load(); 41 | var interval = parseInt(this.options.autoload); 42 | if (!isNaN(interval)){ 43 | var widgster = this; 44 | this._autoloadInterval = setInterval(function(){ 45 | widgster.load(); 46 | }, interval) 47 | } 48 | }; 49 | 50 | Widgster.DEFAULTS = { 51 | collapsed: false, 52 | fullscreened: false, 53 | transitionDuration: 150, 54 | bodySelector: '.body', 55 | showLoader: true, 56 | autoload: false, 57 | loaderTemplate: '
Loading...
', 58 | /** 59 | * provide a way to insert a prompt before removing widget 60 | * @param callback 61 | */ 62 | closePrompt: function(callback){ 63 | callback() 64 | } 65 | }; 66 | 67 | Widgster.prototype.collapse = function(animate){ 68 | animate = typeof animate == "undefined" ? true : animate; 69 | var e = $.Event('collapse.widgster'); 70 | this.$element.trigger(e); 71 | if (e.isDefaultPrevented()) return; 72 | 73 | var widgster = this, 74 | duration = animate ? this.options.transitionDuration : 0; 75 | this.$element.find(this.options.bodySelector).slideUp(duration, function(){ 76 | widgster.$element.addClass('collapsed'); 77 | widgster.$element.trigger($.Event('collapsed.widgster')); 78 | widgster.collapsed = true; 79 | }); 80 | 81 | this.$collapse.hide(); 82 | this.$expand.show(); 83 | 84 | return false; 85 | }; 86 | 87 | Widgster.prototype.expand = function(animate){ 88 | animate = typeof animate == "undefined" ? true : animate; 89 | var e = $.Event('expand.widgster'); 90 | this.$element.trigger(e); 91 | if (e.isDefaultPrevented()) return; 92 | 93 | var widgster = this, 94 | duration = animate ? this.options.transitionDuration : 0; 95 | this.$element.find(this.options.bodySelector).slideDown(duration, function(){ 96 | widgster.$element.removeClass('collapsed'); 97 | widgster.$element.trigger($.Event('expanded.widgster')); 98 | widgster.collapsed = false; 99 | }); 100 | 101 | this.$collapse.show(); 102 | this.$expand.hide(); 103 | 104 | return false; 105 | }; 106 | 107 | Widgster.prototype.close = function(){ 108 | 109 | this.options.closePrompt && this.options.closePrompt($.proxy(this._doClose, this)); 110 | 111 | return false; 112 | }; 113 | 114 | Widgster.prototype.load = function(){ 115 | var e = $.Event('load.widgster'); 116 | 117 | this.$element.trigger(e); 118 | 119 | if (e.isDefaultPrevented()) return; 120 | 121 | var widgster = this; 122 | this.$element.find(this.options.bodySelector).load(this.options.load, function(responseText, textStatus, xhr){ 123 | widgster.expand(); 124 | widgster.options.showLoader && widgster._hideLoader(); 125 | widgster.$element.trigger($.Event('loaded.widgster', { 126 | responseText: responseText, 127 | textStatus: textStatus, 128 | xhr: xhr 129 | })) 130 | }); 131 | this.options.showLoader && this._showLoader(); 132 | 133 | return false; 134 | }; 135 | 136 | Widgster.prototype.fullscreen = function(){ 137 | var e = $.Event('fullscreen.widgster'); 138 | 139 | this.$element.trigger(e); 140 | 141 | if (e.isDefaultPrevented()) return; 142 | 143 | this.$element.css({ 144 | position: 'fixed', 145 | top: 0, 146 | right: 0, 147 | bottom: 0, 148 | left: 0, 149 | margin: 0, 150 | 'z-index': 10000 151 | }); 152 | $('body').css('overflow', 'hidden'); 153 | 154 | this.wasCollapsed = this.collapsed; 155 | this.expand(false); 156 | 157 | this.$fullscreen.hide(); 158 | this.$restore.show(); 159 | 160 | this.$collapse.hide(); this.$expand.hide(); 161 | 162 | this.$element.addClass('fullscreened'); 163 | 164 | this.$element.trigger($.Event('fullscreened.widgster')); 165 | 166 | return false; 167 | }; 168 | 169 | Widgster.prototype.restore = function(){ 170 | var e = $.Event('restore.widgster'); 171 | 172 | this.$element.trigger(e); 173 | 174 | if (e.isDefaultPrevented()) return; 175 | 176 | this.$element.css({ 177 | position: '', 178 | top: '', 179 | right: '', 180 | bottom: '', 181 | left: '', 182 | margin: '', 183 | 'z-index': '' 184 | }); 185 | $('body').css('overflow', ''); 186 | 187 | this.$fullscreen.show(); 188 | this.$restore.hide(); 189 | 190 | if (this.collapsed){ 191 | this.$collapse.hide(); this.$expand.show(); 192 | } else { 193 | this.$collapse.show(); this.$expand.hide(); 194 | } 195 | 196 | this.wasCollapsed && this.collapse(false); 197 | 198 | this.$element.removeClass('fullscreened'); 199 | 200 | this.$element.trigger($.Event('restored.widgster')); 201 | 202 | return false; 203 | }; 204 | 205 | Widgster.prototype._doClose = function(){ 206 | //could have been remove.widgster, but http://bugs.jquery.com/ticket/14600 207 | var e = $.Event('close.widgster'); 208 | 209 | this.$element.trigger(e); 210 | 211 | if (e.isDefaultPrevented()) return; 212 | 213 | $('body').css('overflow', ''); 214 | 215 | this.$element.detach(); 216 | 217 | e = $.Event('closed.widgster', {$element: this.$element}); 218 | 219 | this.$element.trigger(e); 220 | }; 221 | 222 | Widgster.prototype._showLoader = function(){ 223 | var $body = this.$element.find(this.options.bodySelector); 224 | 225 | this.$loaderWrap = this.$element.find('.widgster-loader-wrap'); 226 | 227 | //create loader html if does not exist 228 | if (this.$loaderWrap.length == 0){ 229 | this.$loaderWrap = $(''); 231 | this.$element.append(this.$loaderWrap); 232 | } 233 | this.$loaderWrap.html(this.options.loaderTemplate); 234 | this.$loaderWrap.css({ 235 | 'margin-top': $body.position().top 236 | }); 237 | if (!this.collapsed){ 238 | $body.fadeTo(this.options.transitionDuration, 0); 239 | this.$loaderWrap.fadeIn(this.options.transitionDuration) 240 | } 241 | }; 242 | 243 | Widgster.prototype._hideLoader = function(){ 244 | this.$loaderWrap.fadeOut(this.options.transitionDuration); 245 | this.$element.find(this.options.bodySelector).fadeTo(this.options.transitionDuration, 1); 246 | }; 247 | 248 | /** 249 | * Attach all required widgster functions to data-widgster elements. 250 | * @private 251 | */ 252 | Widgster.prototype._initHandlers = function(){ 253 | this.$element.on('click.collapse.widgster', '[data-widgster=collapse]', $.proxy(this.collapse, this)); 254 | this.$element.on('click.expand.widgster', '[data-widgster=expand]', $.proxy(this.expand, this)); 255 | this.$element.on('click.close.widgster', '[data-widgster=close]', $.proxy(this.close, this)); 256 | this.$element.on('click.load.widgster', '[data-widgster=load]', $.proxy(this.load, this)); 257 | this.$element.on('click.fullscreen.widgster', '[data-widgster=fullscreen]', $.proxy(this.fullscreen, this)); 258 | this.$element.on('click.restore.widgster', '[data-widgster=restore]', $.proxy(this.restore, this)); 259 | }; 260 | 261 | 262 | // NAMESPACED DATA ATTRIBUTES 263 | // ======================= 264 | 265 | function getNamespacedData(namespace, data){ 266 | var namespacedData = {}; 267 | for (var key in data){ 268 | // key starts with namespace 269 | if (key.slice(0, namespace.length) == namespace){ 270 | var namespacedKey = key.slice(namespace.length, key.length); 271 | namespacedKey = namespacedKey.charAt(0).toLowerCase() + namespacedKey.slice(1); 272 | namespacedData[namespacedKey] = data[key]; 273 | } 274 | } 275 | 276 | return namespacedData; 277 | } 278 | 279 | // WIDGSTER PLUGIN DEFINITION 280 | // ======================= 281 | 282 | $.fn.widgster = function (option) { 283 | return this.each(function () { 284 | var $this = $(this); 285 | var data = $this.data('widgster'); 286 | var options = $.extend({}, Widgster.DEFAULTS, getNamespacedData('widgster', $this.data()), typeof option == 'object' && option); 287 | 288 | if (!data) $this.data('widgster', new Widgster(this, options)); 289 | if (typeof option == 'string') data[option](); 290 | }) 291 | }; 292 | 293 | $.fn.widgster.Constructor = Widgster; 294 | }); --------------------------------------------------------------------------------