Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 espaco 1
/**
2
Core script to handle the entire theme and core functions
3
**/
4
var Layout = function() {
5
 
6
    var layoutImgPath = 'admin/layout2/img/';
7
 
8
    var layoutCssPath = 'admin/layout2/css/';
9
 
10
    var resBreakpointMd = Metronic.getResponsiveBreakpoint('md');
11
 
12
    //* BEGIN:CORE HANDLERS *//
13
    // this function handles responsive layout on screen size resize or mobile device rotate.
14
 
15
    // Set proper height for sidebar and content. The content and sidebar height must be synced always.
16
    var handleSidebarAndContentHeight = function() {
17
        var content = $('.page-content');
18
        var sidebar = $('.page-sidebar');
19
        var body = $('body');
20
        var height;
21
 
22
        if (body.hasClass("page-footer-fixed") === true && body.hasClass("page-sidebar-fixed") === false) {
23
            var available_height = Metronic.getViewPort().height - $('.page-footer').outerHeight() - $('.page-header').outerHeight();
24
            if (content.height() < available_height) {
25
                content.attr('style', 'min-height:' + available_height + 'px');
26
            }
27
        } else {
28
            if (body.hasClass('page-sidebar-fixed')) {
29
                height = _calculateFixedSidebarViewportHeight();
30
                if (body.hasClass('page-footer-fixed') === false) {
31
                    height = height - $('.page-footer').outerHeight();
32
                }
33
            } else {
34
                var headerHeight = $('.page-header').outerHeight();
35
                var footerHeight = $('.page-footer').outerHeight();
36
 
37
                if (Metronic.getViewPort().width < resBreakpointMd) {
38
                    height = Metronic.getViewPort().height - headerHeight - footerHeight;
39
                } else {
40
                    height = sidebar.outerHeight() + 10;
41
                }
42
 
43
                if ((height + headerHeight + footerHeight) <= Metronic.getViewPort().height) {
44
                    height = Metronic.getViewPort().height - headerHeight - footerHeight;
45
                }
46
            }
47
            content.attr('style', 'min-height:' + height + 'px');
48
        }
49
    };
50
 
51
    // Handle sidebar menu links
52
    var handleSidebarMenuActiveLink = function(mode, el) {
53
        var url = location.hash.toLowerCase();    
54
 
55
        var menu = $('.page-sidebar-menu');
56
 
57
        if (mode === 'click' || mode === 'set') {
58
            el = $(el);
59
        } else if (mode === 'match') {
60
            menu.find("li > a").each(function() {
61
                var path = $(this).attr("href").toLowerCase();      
62
                // url match condition         
63
                if (path.length > 1 && url.substr(1, path.length - 1) == path.substr(1)) {
64
                    el = $(this);
65
                    return;
66
                }
67
            });
68
        }
69
 
70
        if (!el || el.size() == 0) {
71
            return;
72
        }
73
 
74
        if (el.attr('href').toLowerCase() === 'javascript:;' || el.attr('href').toLowerCase() === '#') {
75
            return;
76
        }        
77
 
78
        var slideSpeed = parseInt(menu.data("slide-speed"));
79
        var keepExpand = menu.data("keep-expanded");
80
 
81
        // disable active states
82
        menu.find('li.active').removeClass('active');
83
        menu.find('li > a > .selected').remove();
84
 
85
        if (menu.hasClass('page-sidebar-menu-hover-submenu') === false) {
86
            menu.find('li.open').each(function(){
87
                if ($(this).children('.sub-menu').size() === 0) {
88
                    $(this).removeClass('open');
89
                    $(this).find('> a > .arrow.open').removeClass('open');
90
                }                            
91
            });
92
        } else {
93
             menu.find('li.open').removeClass('open');
94
        }
95
 
96
        el.parents('li').each(function () {
97
            $(this).addClass('active');
98
            $(this).find('> a > span.arrow').addClass('open');
99
 
100
            if ($(this).parent('ul.page-sidebar-menu').size() === 1) {
101
                $(this).find('> a').append('<span class="selected"></span>');
102
            }
103
 
104
            if ($(this).children('ul.sub-menu').size() === 1) {
105
                $(this).addClass('open');
106
            }
107
        });
108
 
109
        if (mode === 'click') {
110
            if (Metronic.getViewPort().width < resBreakpointMd && $('.page-sidebar').hasClass("in")) { // close the menu on mobile view while laoding a page 
111
                $('.page-header .responsive-toggler').click();
112
            }
113
        }
114
    };
115
 
116
    // Handle sidebar menu
117
    var handleSidebarMenu = function() {
118
        $('.page-sidebar').on('click', 'li > a', function(e) {
119
 
120
            if (Metronic.getViewPort().width >= resBreakpointMd && $(this).parents('.page-sidebar-menu-hover-submenu').size() === 1) { // exit of hover sidebar menu
121
                return;
122
            }
123
 
124
            if ($(this).next().hasClass('sub-menu') === false) {
125
                if (Metronic.getViewPort().width < resBreakpointMd && $('.page-sidebar').hasClass("in")) { // close the menu on mobile view while laoding a page 
126
                    $('.page-header .responsive-toggler').click();
127
                }
128
                return;
129
            }
130
 
131
            if ($(this).next().hasClass('sub-menu always-open')) {
132
                return;
133
            }
134
 
135
            var parent = $(this).parent().parent();
136
            var the = $(this);
137
            var menu = $('.page-sidebar-menu');
138
            var sub = $(this).next();
139
 
140
            var autoScroll = menu.data("auto-scroll");
141
            var slideSpeed = parseInt(menu.data("slide-speed"));
142
            var keepExpand = menu.data("keep-expanded");
143
 
144
            if (keepExpand !== true) {
145
                parent.children('li.open').children('a').children('.arrow').removeClass('open');
146
                parent.children('li.open').children('.sub-menu:not(.always-open)').slideUp(slideSpeed);
147
                parent.children('li.open').removeClass('open');
148
            }
149
 
150
            var slideOffeset = -200;
151
 
152
            if (sub.is(":visible")) {
153
                $('.arrow', $(this)).removeClass("open");
154
                $(this).parent().removeClass("open");
155
                sub.slideUp(slideSpeed, function() {
156
                    if (autoScroll === true && $('body').hasClass('page-sidebar-closed') === false) {
157
                        if ($('body').hasClass('page-sidebar-fixed')) {
158
                            menu.slimScroll({
159
                                'scrollTo': (the.position()).top
160
                            });
161
                        } else {
162
                            Metronic.scrollTo(the, slideOffeset);
163
                        }
164
                    }
165
                    handleSidebarAndContentHeight();
166
                });
167
            } else {
168
                $('.arrow', $(this)).addClass("open");
169
                $(this).parent().addClass("open");
170
                sub.slideDown(slideSpeed, function() {
171
                    if (autoScroll === true && $('body').hasClass('page-sidebar-closed') === false) {
172
                        if ($('body').hasClass('page-sidebar-fixed')) {
173
                            menu.slimScroll({
174
                                'scrollTo': (the.position()).top
175
                            });
176
                        } else {
177
                            Metronic.scrollTo(the, slideOffeset);
178
                        }
179
                    }
180
                    handleSidebarAndContentHeight();
181
                });
182
            }
183
 
184
            e.preventDefault();
185
        });
186
 
187
        // handle ajax links within sidebar menu
188
        $('.page-sidebar').on('click', ' li > a.ajaxify', function(e) {
189
            e.preventDefault();
190
            Metronic.scrollTop();
191
 
192
            var url = $(this).attr("href");
193
            var menuContainer = $('.page-sidebar ul');
194
            var pageContent = $('.page-content');
195
            var pageContentBody = $('.page-content .page-content-body');
196
 
197
            menuContainer.children('li.active').removeClass('active');
198
            menuContainer.children('arrow.open').removeClass('open');
199
 
200
            $(this).parents('li').each(function() {
201
                $(this).addClass('active');
202
                $(this).children('a > span.arrow').addClass('open');
203
            });
204
            $(this).parents('li').addClass('active');
205
 
206
            if (Metronic.getViewPort().width < resBreakpointMd && $('.page-sidebar').hasClass("in")) { // close the menu on mobile view while laoding a page 
207
                $('.page-header .responsive-toggler').click();
208
            }
209
 
210
            Metronic.startPageLoading();
211
 
212
            var the = $(this);
213
 
214
            $.ajax({
215
                type: "GET",
216
                cache: false,
217
                url: url,
218
                dataType: "html",
219
                success: function(res) {
220
 
221
                    if (the.parents('li.open').size() === 0) {
222
                        $('.page-sidebar-menu > li.open > a').click();
223
                    }
224
 
225
                    Metronic.stopPageLoading();
226
                    pageContentBody.html(res);
227
                    Layout.fixContentHeight(); // fix content height
228
                    Metronic.initAjax(); // initialize core stuff
229
                },
230
                error: function(xhr, ajaxOptions, thrownError) {
231
                    Metronic.stopPageLoading();
232
                    pageContentBody.html('<h4>Could not load the requested content.</h4>');
233
                }
234
            });
235
        });
236
 
237
        // handle ajax link within main content
238
        $('.page-content').on('click', '.ajaxify', function(e) {
239
            e.preventDefault();
240
            Metronic.scrollTop();
241
 
242
            var url = $(this).attr("href");
243
            var pageContent = $('.page-content');
244
            var pageContentBody = $('.page-content .page-content-body');
245
 
246
            Metronic.startPageLoading();
247
 
248
            if (Metronic.getViewPort().width < resBreakpointMd && $('.page-sidebar').hasClass("in")) { // close the menu on mobile view while laoding a page 
249
                $('.page-header .responsive-toggler').click();
250
            }
251
 
252
            $.ajax({
253
                type: "GET",
254
                cache: false,
255
                url: url,
256
                dataType: "html",
257
                success: function(res) {
258
                    Metronic.stopPageLoading();
259
                    pageContentBody.html(res);
260
                    Layout.fixContentHeight(); // fix content height
261
                    Metronic.initAjax(); // initialize core stuff
262
                },
263
                error: function(xhr, ajaxOptions, thrownError) {
264
                    pageContentBody.html('<h4>Could not load the requested content.</h4>');
265
                    Metronic.stopPageLoading();
266
                }
267
            });
268
        });
269
 
270
        // handle scrolling to top on responsive menu toggler click when header is fixed for mobile view
271
        $(document).on('click', '.page-header-fixed-mobile .page-header .responsive-toggler', function(){
272
            Metronic.scrollTop();
273
        });      
274
    };
275
 
276
    // Helper function to calculate sidebar height for fixed sidebar layout.
277
    var _calculateFixedSidebarViewportHeight = function() {
278
        var sidebarHeight = Metronic.getViewPort().height - $('.page-header').outerHeight();
279
        if ($('body').hasClass("page-footer-fixed")) {
280
            sidebarHeight = sidebarHeight - $('.page-footer').outerHeight();
281
        }
282
 
283
        return sidebarHeight;
284
    };
285
 
286
    // Handles fixed sidebar
287
    var handleFixedSidebar = function() {
288
        var menu = $('.page-sidebar-menu');
289
 
290
        Metronic.destroySlimScroll(menu);
291
 
292
        if ($('.page-sidebar-fixed').size() === 0) {
293
            handleSidebarAndContentHeight();
294
            return;
295
        }
296
 
297
        if (Metronic.getViewPort().width >= resBreakpointMd) {
298
            menu.attr("data-height", _calculateFixedSidebarViewportHeight());
299
            Metronic.initSlimScroll(menu);
300
            handleSidebarAndContentHeight();
301
        }
302
    };
303
 
304
    // Handles sidebar toggler to close/hide the sidebar.
305
    var handleFixedSidebarHoverEffect = function () {
306
        var body = $('body');
307
        if (body.hasClass('page-sidebar-fixed')) {
308
            $('.page-sidebar').on('mouseenter', function () {
309
                if (body.hasClass('page-sidebar-closed')) {
310
                    $(this).find('.page-sidebar-menu').removeClass('page-sidebar-menu-closed');
311
                }
312
            }).on('mouseleave', function () {
313
                if (body.hasClass('page-sidebar-closed')) {
314
                    $(this).find('.page-sidebar-menu').addClass('page-sidebar-menu-closed');
315
                }
316
            });
317
        }
318
    };
319
 
320
    // Hanles sidebar toggler
321
    var handleSidebarToggler = function() {
322
        var body = $('body');
323
        if ($.cookie && $.cookie('sidebar_closed') === '1' && Metronic.getViewPort().width >= resBreakpointMd) {
324
            $('body').addClass('page-sidebar-closed');
325
            $('.page-sidebar-menu').addClass('page-sidebar-menu-closed');
326
        }
327
 
328
        // handle sidebar show/hide
329
        $('body').on('click', '.sidebar-toggler', function(e) {
330
            var sidebar = $('.page-sidebar');
331
            var sidebarMenu = $('.page-sidebar-menu');
332
            $(".sidebar-search", sidebar).removeClass("open");
333
 
334
            if (body.hasClass("page-sidebar-closed")) {
335
                body.removeClass("page-sidebar-closed");
336
                sidebarMenu.removeClass("page-sidebar-menu-closed");
337
                if ($.cookie) {
338
                    $.cookie('sidebar_closed', '0');
339
                }
340
            } else {
341
                body.addClass("page-sidebar-closed");
342
                sidebarMenu.addClass("page-sidebar-menu-closed");
343
                if (body.hasClass("page-sidebar-fixed")) {
344
                    sidebarMenu.trigger("mouseleave");
345
                }
346
                if ($.cookie) {
347
                    $.cookie('sidebar_closed', '1');
348
                }
349
            }
350
 
351
            $(window).trigger('resize');
352
        });
353
 
354
        handleFixedSidebarHoverEffect();
355
 
356
        // handle the search bar close
357
        $('.page-sidebar').on('click', '.sidebar-search .remove', function(e) {
358
            e.preventDefault();
359
            $('.sidebar-search').removeClass("open");
360
        });
361
 
362
        // handle the search query submit on enter press
363
        $('.page-sidebar .sidebar-search').on('keypress', 'input.form-control', function(e) {
364
            if (e.which == 13) {
365
                $('.sidebar-search').submit();
366
                return false; //<---- Add this line
367
            }
368
        });
369
 
370
        // handle the search submit(for sidebar search and responsive mode of the header search)
371
        $('.sidebar-search .submit').on('click', function(e) {
372
            e.preventDefault();
373
            if ($('body').hasClass("page-sidebar-closed")) {
374
                if ($('.sidebar-search').hasClass('open') === false) {
375
                    if ($('.page-sidebar-fixed').size() === 1) {
376
                        $('.page-sidebar .sidebar-toggler').click(); //trigger sidebar toggle button
377
                    }
378
                    $('.sidebar-search').addClass("open");
379
                } else {
380
                    $('.sidebar-search').submit();
381
                }
382
            } else {
383
                $('.sidebar-search').submit();
384
            }
385
        });
386
 
387
        // handle close on body click
388
        if ($('.sidebar-search').size() !== 0) {
389
            $('.sidebar-search .input-group').on('click', function(e) {
390
                e.stopPropagation();
391
            });
392
 
393
            $('body').on('click', function() {
394
                if ($('.sidebar-search').hasClass('open')) {
395
                    $('.sidebar-search').removeClass("open");
396
                }
397
            });
398
        }
399
    };
400
 
401
    // Handles the horizontal menu
402
    var handleHeader = function() {
403
        // handle search box expand/collapse        
404
        $('.page-header').on('click', '.search-form', function(e) {
405
            $(this).addClass("open");
406
            $(this).find('.form-control').focus();
407
 
408
            $('.page-header .search-form .form-control').on('blur', function(e) {
409
                $(this).closest('.search-form').removeClass("open");
410
                $(this).unbind("blur");
411
            });
412
        });
413
 
414
        // handle hor menu search form on enter press
415
        $('.page-header').on('keypress', '.hor-menu .search-form .form-control', function(e) {
416
            if (e.which == 13) {
417
                $(this).closest('.search-form').submit();
418
                return false;
419
            }
420
        });
421
 
422
        // handle header search button click
423
        $('.page-header').on('mousedown', '.search-form.open .submit', function(e) {
424
            e.preventDefault();
425
            e.stopPropagation();
426
            $(this).closest('.search-form').submit();
427
        });
428
    };
429
 
430
    // Handles Bootstrap Tabs.
431
    var handleTabs = function() {
432
        // fix content height on tab click
433
        $('body').on('shown.bs.tab', 'a[data-toggle="tab"]', function() {
434
            handleSidebarAndContentHeight();
435
        });
436
    };
437
 
438
    // Handles the go to top button at the footer
439
    var handleGoTop = function() {
440
        var offset = 300;
441
        var duration = 500;
442
 
443
        if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) { // ios supported
444
            $(window).bind("touchend touchcancel touchleave", function(e) {
445
                if ($(this).scrollTop() > offset) {
446
                    $('.scroll-to-top').fadeIn(duration);
447
                } else {
448
                    $('.scroll-to-top').fadeOut(duration);
449
                }
450
            });
451
        } else { // general 
452
            $(window).scroll(function() {
453
                if ($(this).scrollTop() > offset) {
454
                    $('.scroll-to-top').fadeIn(duration);
455
                } else {
456
                    $('.scroll-to-top').fadeOut(duration);
457
                }
458
            });
459
        }
460
 
461
        $('.scroll-to-top').click(function(e) {
462
            e.preventDefault();
463
            $('html, body').animate({
464
                scrollTop: 0
465
            }, duration);
466
            return false;
467
        });
468
    };
469
 
470
    // Hanlde 100% height elements(block, portlet, etc)
471
    var handle100HeightContent = function() {
472
 
473
        var target = $('.full-height-content');
474
        var height;
475
 
476
        if (!target.hasClass('portlet')) {
477
            return;
478
        }
479
 
480
        height = Metronic.getViewPort().height -
481
            $('.page-header').outerHeight(true) -
482
            $('.page-footer').outerHeight(true) -
483
            $('.page-title').outerHeight(true) -
484
            $('.page-bar').outerHeight(true);
485
 
486
        if ($('body').hasClass('page-header-fixed')) {
487
            height = height - $('.page-header').outerHeight(true);
488
        }
489
 
490
        var portletBody = target.find('.portlet-body');
491
 
492
        if (Metronic.getViewPort().width < resBreakpointMd) {
493
            Metronic.destroySlimScroll(portletBody.find('.full-height-content-body')); // destroy slimscroll 
494
            return;
495
        }
496
 
497
        if (target.find('.portlet-title')) {
498
            height = height - target.find('.portlet-title').outerHeight(true);
499
        }
500
 
501
        height = height - parseInt(portletBody.css("padding-top"));
502
        height = height - parseInt(portletBody.css("padding-bottom"));
503
 
504
        if (target.hasClass("full-height-content-scrollable")) {
505
            portletBody.find('.full-height-content-body').css('height', height);
506
            Metronic.initSlimScroll(portletBody.find('.full-height-content-body'));
507
        } else {
508
            portletBody.css('min-height', height);
509
        }
510
    };
511
 
512
    //* END:CORE HANDLERS *//
513
 
514
    return {
515
 
516
        // Main init methods to initialize the layout
517
        // IMPORTANT!!!: Do not modify the core handlers call order.
518
 
519
        initHeader: function() {
520
            handleHeader(); // handles horizontal menu    
521
        },
522
 
523
        setSidebarMenuActiveLink: function(mode, el) {
524
            handleSidebarMenuActiveLink(mode, el);
525
        },
526
 
527
        initSidebar: function() {
528
            //layout handlers
529
            handleFixedSidebar(); // handles fixed sidebar menu
530
            handleSidebarMenu(); // handles main menu
531
            handleSidebarToggler(); // handles sidebar hide/show
532
 
533
            if (Metronic.isAngularJsApp()) {      
534
                handleSidebarMenuActiveLink('match'); // init sidebar active links 
535
            }
536
 
537
            Metronic.addResizeHandler(handleFixedSidebar); // reinitialize fixed sidebar on window resize
538
        },
539
 
540
        initContent: function() {
541
            handle100HeightContent(); // handles 100% height elements(block, portlet, etc)
542
            handleTabs(); // handle bootstrah tabs
543
 
544
            Metronic.addResizeHandler(handleSidebarAndContentHeight); // recalculate sidebar & content height on window resize
545
            Metronic.addResizeHandler(handle100HeightContent); // reinitialize content height on window resize 
546
        },
547
 
548
        initFooter: function() {
549
            handleGoTop(); //handles scroll to top functionality in the footer
550
        },
551
 
552
        init: function () {            
553
            this.initHeader();
554
            this.initSidebar();
555
            this.initContent();
556
            this.initFooter();
557
        },
558
 
559
        //public function to fix the sidebar and content height accordingly
560
        fixContentHeight: function() {
561
            handleSidebarAndContentHeight();
562
        },
563
 
564
        initFixedSidebarHoverEffect: function() {
565
            handleFixedSidebarHoverEffect();
566
        },
567
 
568
        initFixedSidebar: function() {
569
            handleFixedSidebar();
570
        },
571
 
572
        getLayoutImgPath: function() {
573
            return Metronic.getAssetsPath() + layoutImgPath;
574
        },
575
 
576
        getLayoutCssPath: function() {
577
            return Metronic.getAssetsPath() + layoutCssPath;
578
        }
579
    };
580
 
581
}();