Subversion-Projekte lars-tiefland.cienc

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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