PageSourceSearch

https://www.fpi.it/media/com_docman/js/sidebar.js?98124586

js fpi.it collected 2026-10-02 12:44:22 UTC 11,965 bytes, 293 lines download raw bytes

1/**
2 * DOCman Sidebar
3 *
4 * Customized wrapper for advanced layout logic and behavior for the sidebar.
5 * Uses Bootstrap Affix to make sure the sidebar never scrolls out of view (@TODO can't wait to use CSS4 position:sticky)
6 * Makes sure that the sidebar height matches viewport height.
7 * Allows advanced layout like locking page resize to only resize a mootree list, so that other parts of the sidebar is always visible.
8 * Specializes Affix plugin to work on pages that are responsive, where static top and bottom values would break the layout.
9 * Contains workarounds for Joomla! 3.0 responsive layout hacks that otherwise screws up the sidebar positioning is fixed.
10 *
11 *
12 * @copyright	Copyright (C) 2007 Johan Janssens and Timble CVBA. (http://www.timble.net)
13 * @license		GNU GPLv3 <http://www.gnu.org/licenses/gpl.html>
14 * @requires    Bootstrap Affix plugin
15 */
16
17var Docman = Docman || {};
18
19(function($){
20
21    /* Defining the constructor (same as initialize in MooTools Class) */
22    /**
23     * @param options
24     * @constructor
25     */
26    Docman.Sidebar = function(options){
27
28        //@TODO 'limit' option is automatically passed to php behavior
29        if(options.hasOwnProperty('offset') && !$.isPlainObject(options.offset)) delete options.offset;
30
31        this.setOptions(options);
32
33        this.sidebar  = $(this.options.sidebar);
34        this.target   = this.sidebar.find(this.options.target);
35        this.siblings = this.target.siblings();
36
37        this.observe = this.options.observe ? $(this.options.observe) : this.sidebar.next();
38
39        //Setup the inner container
40        this.target.css('overflow', 'auto');
41
42        //Check if the height is sufficient
43        if(this.options.affix) this.options.affix = this.observe.outerHeight() > $(window).height();
44        this.affix = this.options.affix;
45
46        this.setHeight();
47
48        if(this.options.affix && this.observe.outerHeight()) {
49            this.sidebar.affix({
50                offset: {
51                    top: $.proxy(function(){
52                        if(this.affix) {
53                            return this.sidebar.parent().offset().top - this.options.offset.top;
54                        } else {
55                            return $(document).height();
56                        }
57                    }, this),
58                    bottom: $.proxy(function(){
59                        return $(document).height() - (this.observe.offset().top + this.observe.outerHeight()) + this.options.offset.bottom;
60                    }, this)
61                }
62            });
63        }
64
65        $(window)
66            .on('resize', $.proxy(this.setHeight, this))
67            .on('sidebar:setHeight', $.proxy(this.setHeight, this))
68            .on('sidebar:resizeHeight', $.proxy(function(){
69                //console.log(arguments, this);
70                this.resizeHeight();
71            }, this));
72
73        this.makeCollapsible();
74    };
75
76    Docman.Sidebar.prototype = {
77
78        /**
79         * @constructs DOCman.Sidebar
80         */
81        constructor: Docman.Sidebar,
82
83        /**
84         * @method getDefaults
85         * @returns {{minHeight: number, sidebar: string, target: string, observe: boolean, affix: boolean, offset: {top: number, bottom: number, callback: Function}}}
86         */
87        getDefaults: function(){
88
89            /** @lends DOCman.Sidebar.options */
90            var defaults = {
91                minHeight: 200,
92                sidebar: '.sidebar',
93                target: '.sidebar-inner',
94                padding: {bottom: 50},
95                observe: false, //Pass a css selector if the content area isn't the sidebars next sibling DOM element
96                affix: false, //If Bootstrap's Affix plugin is loaded, this option will make the sidebar scroll with the view
97                offset: {top: 0, bottom: 0, callback: function(){}}
98            };
99
100            if($('.navbar').length) {
101                /**
102                 * @lends DOCman.Sidebar.options.offset.callback
103                 * @this DOCman.Sidebar
104                 */
105                defaults.offset.callback = function(){
106                    this.options.offset.top = this.options.offset.bottom = 0;
107                    /**
108                     * Workarounds for possible fixed UI elements to calculate correct offsets
109                     */
110                    if($('.navbar-fixed-top').css('position') == 'fixed') {
111                        /**
112                         * Top navbar is fixed on desktop layout, static on mobile and tablet
113                         * @type {number}
114                         */
115                        this.options.offset.top += $('.navbar.navbar-fixed-top').outerHeight();
116                    }
117                    var mobile_layout = this._isMobileLayout();
118                    if(mobile_layout) {
119                        if(mobile_layout === 1) {
120                            //Mobile layout not enabled
121                            this.options.offset.top += $('.subhead-collapse .subhead').outerHeight();
122                            this.affix = true;
123                        } else {
124                            //Mobile layout is being enabled
125                            this.affix = false;
126                        }
127                    }
128                    //Navbar at the bottom may exist in both desktop and tablet layout
129                    if($('.navbar-fixed-bottom').is(':visible')) {
130                        /**
131                         * Bottom navbar is fixed on desktop layout and sometimes on tablet laout, always static on mobile
132                         * @type {number}
133                         */
134                        this.options.offset.bottom += $('.navbar-fixed-bottom').outerHeight();
135                    }
136                }
137            }
138
139            return defaults;
140        },
141
142        setOptions: function(options){
143
144            this.options = $.extend(true, {}, this.getDefaults(), options);
145
146            return this;
147        },
148
149        makeCollapsible: function() {
150            var sidebar = $('#documents-sidebar'), storage = window.localStorage || {}, duration;
151            sidebar.find('h3').each(function(i, h3){
152                var $h3 = $(h3), key = 'DOCman#documents-sidebar['+i+']', state = storage[key] != 'closed' ? 'open' : 'closed', panel = $h3.next();
153
154                panel.addClass('sidebar-panel').data('height', panel.height());
155
156                if(!duration) {
157                    panel.addClass('transition-enabled');
158                    duration = parseFloat(panel.css('transition-duration'), 10)*1000;
159                    panel.removeClass('transition-enabled');
160                }
161
162                $h3.addClass(state).on('click', function(){
163                    $(this).toggleClass('open closed');
164
165                    /** trying to animate the height change
166                     if(!$(this).is('.k-js-category-tree') && $('.k-js-category-tree').is(':visible')) {
167                if($(this).hasClass('open')) {
168                    console.warn('ioenung!', '+='+$(this).outerHeight()+'px');
169                    $('.k-js-category-tree').animate({height: '+='+$(this).outerHeight()+'px'}, duration);
170                } else {
171                    $('.k-js-category-tree').animate({height: '-='+$(this).outerHeight()+'px'}, duration);
172                    console.log('-='+$(this).outerHeight()+'px');
173                }
174            }
175                     //*/
176
177                    if($(this).hasClass('closed')) {
178                        panel.css('height', '');
179                        panel.data('height', panel.height());
180                        panel.css('height', panel.height()).addClass('transition-enabled');
181
182                        setTimeout(function(){
183                            panel.addClass('sidebar-panel-closed').css('height', '0px');
184                        }, 0);
185
186                        setTimeout(function() {
187                            panel.removeClass('transition-enabled');
188                        }, duration+100);
189                    } else {
190
191                        panel.addClass('transition-enabled');
192                        setTimeout(function(){
193                            panel.removeClass('sidebar-panel-closed').css('height', panel.data('height'));
194                        }, 0);
195
196                        setTimeout(function() {
197                            panel.removeClass('transition-enabled').css('height', '');
198                            panel.data('height', panel.height());
199                        }, duration+100);
200                    }
201
202                    setTimeout(function() {
203                        //Resets the height of the categories tree
204                        //$(window).trigger('sidebar:resizeHeight', [to_height]); //@TODO animate height change to categories list
205                        $(window).trigger('sidebar:setHeight');
206                    }, duration+100);
207
208                    storage[key] = $h3.hasClass('open') ? 'open' : 'closed';
209                });
210                if(state == 'closed') {
211                    panel.data('height', panel.height());
212                    panel.addClass('sidebar-panel-closed').css('height', '0px');
213                }
214            });
215        },
216
217        /**
218         * @method setHeight
219         *
220         */
221        setHeight: function(){
222
223            if(this.options.offset.callback && this.options.offset.callback.call) this.options.offset.callback.call(this);
224
225            if(this.options.affix) {
226                //Making sure it's positioned correctly
227                $(window).trigger('scroll.affix.data-api');
228
229                //Set the right horizontal offset, this changes as the sidebar collapses in responsive layouts
230                this.sidebar.css({left: this.sidebar.parent().offset().left+1, top: this.options.offset.top});
231            }
232
233            // if mobile layout, remove extra height or reveal overflow
234            var mobile_layout = this._isMobileLayout();
235            if(this.options.affix && mobile_layout > 1) {
236
237                this.target.css('max-height', '');
238
239            } else {
240
241                this.affix = true;
242
243                var offset = 0;
244                if(this.siblings.length) {
245                    this.siblings.each(function(){
246                        if($(this).is(':visible')) offset += $(this).outerHeight();
247                    });
248                }
249
250                //Set the right vertical offset, this changes as the sidebar collapses in responsive layouts
251                offset += this.options.offset.top + this.options.offset.bottom + this.options.padding.bottom;
252
253                var height = $(window).height() - offset;
254                this.target.css('max-height', Math.max(height, this.options.minHeight));
255            }
256
257            //To allow listening to height changes
258            this.target.triggerHandler('resize');
259        },
260
261        /**
262         * Used to update the height, allowing it to be animated
263         * @param height
264         */
265        resizeHeight: function(height){
266
267        },
268
269        /**
270         * Checks if there's a responsive mobile layout available, and whether it's active
271         * @returns {number} 0 = unavailable, 1 = available but disabled, 2 = enabled
272         * @private
273         */
274        _isMobileLayout: function(){
275
276            var result = 0;
277            if($('.subhead-collapse .subhead').length) {
278                result = 1;
279                /**
280                 * Top navbar is fixed on desktop layout, static on mobile and tablet
281                 * NOTE: Hacky but thanks to how the subhead js logic in j!3.0 works we need to do it this way
282                 */
283                var test = $('<div/>', {'class': 'subhead subhead-fixed'}).appendTo(document.body);
284                if(test.css('position') != 'fixed') {
285                    result = 2;
286                }
287                test.remove();
288            }
289
290            return result;
291        }
292    };
293}(window.kQuery));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.