/* * Document : app.js * Author : pixelcave * Description: Custom scripts and plugin initializations */ var App = function() { /* Initialization UI Code */ var uiInit = function() { page = $('#page-container'); pageContent = $('#page-content'); header = $('header'); footer = $('#page-content + footer'); sidebar = $('#sidebar'); sScroll = $('#sidebar-scroll'); sidebarAlt = $('#sidebar-alt'); sScrollAlt = $('#sidebar-alt-scroll'); // Initialize sidebars functionality handleSidebar('init'); // Sidebar navigation functionality handleNav(); // Handle UI scrollToTop(); resizePageContent(); $(window).resize(function(){ resizePageContent(); }); $(window).bind('orientationchange', resizePageContent); // Initialize tabs $('[data-toggle="tabs"] a, .enable-tabs a').click(function(e){ e.preventDefault(); $(this).tab('show'); }); // Initialize Tooltips $('[data-toggle="tooltip"], .enable-tooltip').tooltip({container: 'body', animation: false}); // Initialize Popovers $('[data-toggle="popover"], .enable-popover').popover({container: 'body', animation: true}); // Initialize single image lightbox $('[data-toggle="lightbox-image"]').magnificPopup({type: 'image', image: {titleSrc: 'title'}}); // Initialize image gallery lightbox $('[data-toggle="lightbox-gallery"]').magnificPopup({ delegate: 'a.gallery-link', type: 'image', gallery: { enabled: true, navigateByImgClick: true, arrowMarkup: '', tPrev: 'Previous', tNext: 'Next', tCounter: '%curr% of %total%' }, image: {titleSrc: 'title'} }); // Initialize Placeholder $('input, textarea').placeholder(); // Initialize Chosen $('.select-chosen').chosen({width: "100%"}); // Initialize Select2 $('.select-select2').select2(); // Toggle animation class when an element appears with Jquery Appear plugin $('[data-toggle="animation-appear"]').each(function(){ var is_xs_disable = $(this).attr('data-xs-disabled'); var $this = $(this); var $animClass = $this.attr('data-animation-class'); if($(window).width()<992){ $this.removeClass('invisible'); return; } // var $elemOff = $this.attr('data-element-offset'); $this.appear(function() { $this.addClass($animClass); setTimeout(function(){ $this.removeClass('invisible'); },300) }); }); }; /* Page Loading functionality */ var pageLoading = function(){ var pageWrapper = $('#page-wrapper'); if (pageWrapper.hasClass('page-loading')) { pageWrapper.removeClass('page-loading'); } }; var isMobile = function() { //console.log("Navigator: " + navigator.userAgent); return /(iphone|ipod|ipad|android|blackberry|windows ce|palm|symbian)/i.test(navigator.userAgent); }; /* Sidebar Functionality */ var handleSidebar = function(mode, extra) { if (mode === 'init') { // Init sidebars scrolling functionality handleSidebar('sidebar-scroll'); handleSidebar('sidebar-alt-scroll'); // Close the other sidebar if we hover over a partial one // In smaller screens (the same applies to resized browsers) two visible sidebars // could mess up our main content (not enough space), so we hide the other one :-) $('.sidebar-partial #sidebar') .mouseenter(function(){ handleSidebar('close-sidebar-alt'); }); $('.sidebar-alt-partial #sidebar-alt') .mouseenter(function(){ handleSidebar('close-sidebar'); }); } else { var windowW = getWindowWidth(); if (mode === 'toggle-sidebar') { if ( windowW > 991) { // Toggle main sidebar in large screens (> 991px) page.toggleClass('sidebar-visible-lg'); if (page.hasClass('sidebar-mini')) { page.toggleClass('sidebar-visible-lg-mini'); } if (page.hasClass('sidebar-visible-lg')) { handleSidebar('close-sidebar-alt'); } // If 'toggle-other' is set, open the alternative sidebar when we close this one if (extra === 'toggle-other') { if (!page.hasClass('sidebar-visible-lg')) { handleSidebar('open-sidebar-alt'); } } } else { // Toggle main sidebar in small screens (< 992px) page.toggleClass('sidebar-visible-xs'); if (page.hasClass('sidebar-visible-xs')) { handleSidebar('close-sidebar-alt'); } } // Handle main sidebar scrolling functionality handleSidebar('sidebar-scroll'); } else if (mode === 'toggle-sidebar-alt') { if ( windowW > 991) { // Toggle alternative sidebar in large screens (> 991px) page.toggleClass('sidebar-alt-visible-lg'); if (page.hasClass('sidebar-alt-visible-lg')) { handleSidebar('close-sidebar'); } // If 'toggle-other' is set open the main sidebar when we close the alternative if (extra === 'toggle-other') { if (!page.hasClass('sidebar-alt-visible-lg')) { handleSidebar('open-sidebar'); } } } else { // Toggle alternative sidebar in small screens (< 992px) page.toggleClass('sidebar-alt-visible-xs'); if (page.hasClass('sidebar-alt-visible-xs')) { handleSidebar('close-sidebar'); } } } else if (mode === 'open-sidebar') { if ( windowW > 991) { // Open main sidebar in large screens (> 991px) if (page.hasClass('sidebar-mini')) { page.removeClass('sidebar-visible-lg-mini'); } page.addClass('sidebar-visible-lg'); } else { // Open main sidebar in small screens (< 992px) page.addClass('sidebar-visible-xs'); } // Close the other sidebar handleSidebar('close-sidebar-alt'); } else if (mode === 'open-sidebar-alt') { if ( windowW > 991) { // Open alternative sidebar in large screens (> 991px) page.addClass('sidebar-alt-visible-lg'); } else { // Open alternative sidebar in small screens (< 992px) page.addClass('sidebar-alt-visible-xs'); } // Close the other sidebar handleSidebar('close-sidebar'); } else if (mode === 'close-sidebar') { if ( windowW > 991) { // Close main sidebar in large screens (> 991px) page.removeClass('sidebar-visible-lg'); if (page.hasClass('sidebar-mini')) { page.addClass('sidebar-visible-lg-mini'); } } else { // Close main sidebar in small screens (< 992px) page.removeClass('sidebar-visible-xs'); } } else if (mode === 'close-sidebar-alt') { if ( windowW > 991) { // Close alternative sidebar in large screens (> 991px) page.removeClass('sidebar-alt-visible-lg'); } else { // Close alternative sidebar in small screens (< 992px) page.removeClass('sidebar-alt-visible-xs'); } } else if (mode == 'sidebar-scroll') { // Handle main sidebar scrolling if (page.hasClass('sidebar-mini') && page.hasClass('sidebar-visible-lg-mini') && (windowW > 991)) { // Destroy main sidebar scrolling when in mini sidebar mode if (sScroll.length && sScroll.parent('.slimScrollDiv').length) { sScroll .slimScroll({destroy: true}); sScroll .attr('style', ''); } } else if ((page.hasClass('header-fixed-top') || page.hasClass('header-fixed-bottom'))) { var sHeight = $(window).height(); if (sScroll.length && (!sScroll.parent('.slimScrollDiv').length)) { // If scrolling does not exist init it.. sScroll .slimScroll({ height: sHeight, color: '#fff', size: '3px', touchScrollStep: 100 }); // Handle main sidebar's scrolling functionality on resize or orientation change var sScrollTimeout; $(window).on('resize orientationchange', function(){ clearTimeout(sScrollTimeout); sScrollTimeout = setTimeout(function(){ handleSidebar('sidebar-scroll'); }, 150); }); } else { // ..else resize scrolling height sScroll .add(sScroll.parent()) .css('height', sHeight); } } } else if (mode == 'sidebar-alt-scroll') { // Init alternative sidebar scrolling if ((page.hasClass('header-fixed-top') || page.hasClass('header-fixed-bottom'))) { var sHeightAlt = $(window).height(); if (sScrollAlt.length && (!sScrollAlt.parent('.slimScrollDiv').length)) { // If scrolling does not exist init it.. sScrollAlt .slimScroll({ height: sHeightAlt, color: '#fff', size: '3px', touchScrollStep: 100 }); // Resize alternative sidebar scrolling height on window resize or orientation change var sScrollAltTimeout; $(window).on('resize orientationchange', function(){ clearTimeout(sScrollAltTimeout); sScrollAltTimeout = setTimeout(function(){ handleSidebar('sidebar-alt-scroll'); }, 150); }); } else { // ..else resize scrolling height sScrollAlt .add(sScrollAlt.parent()) .css('height', sHeightAlt); } } } } return false; }; /* Gets window width cross browser */ var getWindowWidth = function(){ return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; }; /* Sidebar Navigation functionality */ var handleNav = function() { // Animation Speed, change the values for different results var upSpeed = 250; var downSpeed = 250; // Get all vital links var menuLinks = $('.sidebar-nav-menu'); var submenuLinks = $('.sidebar-nav-submenu'); // Primary Accordion functionality menuLinks.click(function(){ var link = $(this); if (page.hasClass('sidebar-mini') && page.hasClass('sidebar-visible-lg-mini') && (getWindowWidth() > 991)) { if (link.hasClass('open')) { link.removeClass('open'); } else { $('.sidebar-nav-menu.open').removeClass('open'); link.addClass('open'); } } else if (!link.parent().hasClass('active')) { if (link.hasClass('open')) { link.removeClass('open').next().slideUp(upSpeed, function(){ handlePageScroll(link, 200, 300); }); // Resize #page-content to fill empty space if exists setTimeout(resizePageContent, upSpeed); } else { $('.sidebar-nav-menu.open').removeClass('open').next().slideUp(upSpeed); link.addClass('open').next().slideDown(downSpeed, function(){ handlePageScroll(link, 150, 600); }); // Resize #page-content to fill empty space if exists setTimeout(resizePageContent, ((upSpeed > downSpeed) ? upSpeed : downSpeed)); } } return false; }); // Submenu Accordion functionality submenuLinks.click(function(){ var link = $(this); if (link.parent().hasClass('active') !== true) { if (link.hasClass('open')) { link.removeClass('open').next().slideUp(upSpeed, function(){ handlePageScroll(link, 200, 300); }); // Resize #page-content to fill empty space if exists setTimeout(resizePageContent, upSpeed); } else { link.closest('ul').find('.sidebar-nav-submenu.open').removeClass('open').next().slideUp(upSpeed); link.addClass('open').next().slideDown(downSpeed, function(){ handlePageScroll(link, 150, 600); }); // Resize #page-content to fill empty space if exists setTimeout(resizePageContent, ((upSpeed > downSpeed) ? upSpeed : downSpeed)); } } return false; }); }; /* Scrolls the page (static layout) or the sidebar scroll element (fixed header/sidebars layout) to a specific position - Used when a submenu opens */ var handlePageScroll = function(sElem, sHeightDiff, sSpeed) { if (!page.hasClass('disable-menu-autoscroll')) { var elemScrollToHeight; // If we have a static layout scroll the page // if (!header.hasClass('navbar-fixed-top') && !header.hasClass('navbar-fixed-bottom')) { // var elemOffsetTop = sElem.offset().top; // elemScrollToHeight = (((elemOffsetTop - sHeightDiff) > 0) ? (elemOffsetTop - sHeightDiff) : 0); // $('html, body').animate({scrollTop: elemScrollToHeight}, sSpeed); // } else { // If we have a fixed header/sidebars layout scroll the sidebar scroll element var sContainer = sElem.parents('#sidebar-scroll'); var elemOffsetCon = sElem.offset().top + Math.abs($('div:first', sContainer).offset().top); elemScrollToHeight = (((elemOffsetCon - sHeightDiff) > 0) ? (elemOffsetCon - sHeightDiff) : 0); sContainer.animate({ scrollTop: elemScrollToHeight}, sSpeed); // } } }; /* Sidebar Functionality */ var handleSidebar = function(mode, extra) { if (mode === 'init') { // Init sidebars scrolling functionality handleSidebar('sidebar-scroll'); handleSidebar('sidebar-alt-scroll'); // Close the other sidebar if we hover over a partial one // In smaller screens (the same applies to resized browsers) two visible sidebars // could mess up our main content (not enough space), so we hide the other one :-) $('.sidebar-partial #sidebar') .mouseenter(function(){ handleSidebar('close-sidebar-alt'); }); $('.sidebar-alt-partial #sidebar-alt') .mouseenter(function(){ handleSidebar('close-sidebar'); }); } else { var windowW = getWindowWidth(); if (mode === 'toggle-sidebar') { if ( windowW > 991) { // Toggle main sidebar in large screens (> 991px) page.toggleClass('sidebar-visible-lg'); if (page.hasClass('sidebar-mini')) { page.toggleClass('sidebar-visible-lg-mini'); } if (page.hasClass('sidebar-visible-lg')) { handleSidebar('close-sidebar-alt'); } // If 'toggle-other' is set, open the alternative sidebar when we close this one if (extra === 'toggle-other') { if (!page.hasClass('sidebar-visible-lg')) { handleSidebar('open-sidebar-alt'); } } } else { // Toggle main sidebar in small screens (< 992px) page.toggleClass('sidebar-visible-xs'); if (page.hasClass('sidebar-visible-xs')) { handleSidebar('close-sidebar-alt'); } } // Handle main sidebar scrolling functionality handleSidebar('sidebar-scroll'); } else if (mode === 'toggle-sidebar-alt') { if ( windowW > 991) { // Toggle alternative sidebar in large screens (> 991px) page.toggleClass('sidebar-alt-visible-lg'); if (page.hasClass('sidebar-alt-visible-lg')) { handleSidebar('close-sidebar'); } // If 'toggle-other' is set open the main sidebar when we close the alternative if (extra === 'toggle-other') { if (!page.hasClass('sidebar-alt-visible-lg')) { handleSidebar('open-sidebar'); } } } else { // Toggle alternative sidebar in small screens (< 992px) page.toggleClass('sidebar-alt-visible-xs'); if (page.hasClass('sidebar-alt-visible-xs')) { handleSidebar('close-sidebar'); } } } else if (mode === 'open-sidebar') { if ( windowW > 991) { // Open main sidebar in large screens (> 991px) if (page.hasClass('sidebar-mini')) { page.removeClass('sidebar-visible-lg-mini'); } page.addClass('sidebar-visible-lg'); } else { // Open main sidebar in small screens (< 992px) page.addClass('sidebar-visible-xs'); } // Close the other sidebar handleSidebar('close-sidebar-alt'); } else if (mode === 'open-sidebar-alt') { if ( windowW > 991) { // Open alternative sidebar in large screens (> 991px) page.addClass('sidebar-alt-visible-lg'); } else { // Open alternative sidebar in small screens (< 992px) page.addClass('sidebar-alt-visible-xs'); } // Close the other sidebar handleSidebar('close-sidebar'); } else if (mode === 'close-sidebar') { if ( windowW > 991) { // Close main sidebar in large screens (> 991px) page.removeClass('sidebar-visible-lg'); if (page.hasClass('sidebar-mini')) { page.addClass('sidebar-visible-lg-mini'); } } else { // Close main sidebar in small screens (< 992px) page.removeClass('sidebar-visible-xs'); } } else if (mode === 'close-sidebar-alt') { if ( windowW > 991) { // Close alternative sidebar in large screens (> 991px) page.removeClass('sidebar-alt-visible-lg'); } else { // Close alternative sidebar in small screens (< 992px) page.removeClass('sidebar-alt-visible-xs'); } } else if (mode == 'sidebar-scroll') { // Handle main sidebar scrolling if (page.hasClass('sidebar-mini') && page.hasClass('sidebar-visible-lg-mini') && (windowW > 991)) { // Destroy main sidebar scrolling when in mini sidebar mode if (sScroll.length && sScroll.parent('.slimScrollDiv').length) { sScroll .slimScroll({destroy: true}); sScroll .attr('style', ''); } } else if ((page.hasClass('header-fixed-top') || page.hasClass('header-fixed-bottom'))) { var sHeight = $(window).height(); if (sScroll.length && (!sScroll.parent('.slimScrollDiv').length)) { // If scrolling does not exist init it.. sScroll .slimScroll({ height: sHeight, color: '#fff', size: '3px', touchScrollStep: 100 }); // Handle main sidebar's scrolling functionality on resize or orientation change var sScrollTimeout; $(window).on('resize orientationchange', function(){ clearTimeout(sScrollTimeout); sScrollTimeout = setTimeout(function(){ handleSidebar('sidebar-scroll'); }, 150); }); } else { // ..else resize scrolling height sScroll .add(sScroll.parent()) .css('height', sHeight); } } } else if (mode == 'sidebar-alt-scroll') { // Init alternative sidebar scrolling if ((page.hasClass('header-fixed-top') || page.hasClass('header-fixed-bottom'))) { var sHeightAlt = $(window).height(); if (sScrollAlt.length && (!sScrollAlt.parent('.slimScrollDiv').length)) { // If scrolling does not exist init it.. sScrollAlt .slimScroll({ height: sHeightAlt, color: '#fff', size: '3px', touchScrollStep: 100 }); // Resize alternative sidebar scrolling height on window resize or orientation change var sScrollAltTimeout; $(window).on('resize orientationchange', function(){ clearTimeout(sScrollAltTimeout); sScrollAltTimeout = setTimeout(function(){ handleSidebar('sidebar-alt-scroll'); }, 150); }); } else { // ..else resize scrolling height sScrollAlt .add(sScrollAlt.parent()) .css('height', sHeightAlt); } } } } return false; }; /* Resize #page-content to fill empty space if exists */ var resizePageContent = function() { var windowH = $(window).height(); var sidebarH = sidebar.outerHeight(); var sidebarAltH = sidebarAlt.outerHeight(); var headerH = header.outerHeight(); var footerH = footer.outerHeight(); // If we have a fixed sidebar/header layout or each sidebars’ height < window height if (header.hasClass('navbar-fixed-top') || header.hasClass('navbar-fixed-bottom') || ((sidebarH < windowH) && (sidebarAltH < windowH))) { if (page.hasClass('footer-fixed')) { // if footer is fixed don't remove its height pageContent.css('min-height', windowH - headerH + 'px'); } else { // else if footer is static, remove its height pageContent.css('min-height', windowH - (headerH + footerH) + 'px'); } } else { // In any other case set #page-content height the same as biggest sidebar's height if (page.hasClass('footer-fixed')) { // if footer is fixed don't remove its height pageContent.css('min-height', ((sidebarH > sidebarAltH) ? sidebarH : sidebarAltH) - headerH + 'px'); } else { // else if footer is static, remove its height pageContent.css('min-height', ((sidebarH > sidebarAltH) ? sidebarH : sidebarAltH) - (headerH + footerH) + 'px'); } } if (page.hasClass('sidebar-alt-visible-xs') && $(window).width() > 990) { handleSidebar('close-sidebar'); page.toggleClass('sidebar-alt-visible-xs'); } }; /* Scroll to top functionality */ var scrollToTop = function() { // Get link var link = $('#to-top'); var windowW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; $(window).scroll(function() { // If the user scrolled a bit (150 pixels) show the link in large resolutions if (($(this).scrollTop() > 150)) { link.fadeIn(100); } else { link.fadeOut(100); } }); // On click get to top link.click(function() { $('html, body').animate({scrollTop: 0}, 500); return false; }); }; $(".scroll-nav").sticky({ topSpacing: 0 }); return { init: function() { uiInit(); // Initialize UI Code }, sidebar: function(mode, extra) { handleSidebar(mode, extra); // Handle sidebars - access functionality from everywhere } }; }(); /* Initialize app when page loads */ $(function(){ App.init(); });