123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565 |
- /* ------------------------------------------------------------------------------
- *
- * # Template JS core
- *
- * Includes minimum required JS code for proper template functioning
- *
- * ---------------------------------------------------------------------------- */
- // Setup module
- // ------------------------------
- const App = function () {
- // Utils
- // -------------------------
- //
- // Transitions
- //
- // Disable all transitions
- const transitionsDisabled = function() {
- $('body').addClass('no-transitions');
- };
- // Enable all transitions
- const transitionsEnabled = function() {
- $('body').removeClass('no-transitions');
- };
- //
- // Detect OS to apply custom scrollbars
- //
- // Custom scrollbar style is controlled by CSS. This function is needed to keep default
- // scrollbars on MacOS and avoid usage of extra JS libraries
- const detectOS = function() {
- const platform = window.navigator.platform,
- windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'],
- customScrollbarsClass = 'custom-scrollbars';
- // Add class if OS is windows
- windowsPlatforms.indexOf(platform) != -1 && $('body').addClass(customScrollbarsClass);
- };
- // Sidebars
- // -------------------------
- //
- // On desktop
- //
- // Resize main sidebar
- const sidebarMainResize = function() {
- // Elements
- const sidebarMainElement = $('.sidebar-main'),
- sidebarMainToggler = $('.sidebar-main-resize'),
- resizeClass = 'sidebar-main-resized',
- unfoldClass = 'sidebar-main-unfold';
- // Define variables
- const unfoldDelay = 150;
- let timerStart,
- timerFinish;
- // Toggle classes on click
- sidebarMainToggler.on('click', function(e) {
- sidebarMainElement.toggleClass(resizeClass);
- !sidebarMainElement.hasClass(resizeClass) && sidebarMainElement.removeClass(unfoldClass);
- });
- // Add class on mouse enter
- sidebarMainElement.on('mouseenter', function() {
- clearTimeout(timerFinish);
- timerStart = setTimeout(function() {
- sidebarMainElement.hasClass(resizeClass) && sidebarMainElement.addClass(unfoldClass);
- }, unfoldDelay);
- });
- // Remove class on mouse leave
- sidebarMainElement.on('mouseleave', function() {
- clearTimeout(timerStart);
- timerFinish = setTimeout(function() {
- sidebarMainElement.removeClass(unfoldClass);
- }, unfoldDelay);
- });
- };
- // Toggle main sidebar
- const sidebarMainToggle = function() {
- // Elements
- const sidebarMainElement = $('.sidebar-main'),
- sidebarMainRestElements = $('.sidebar:not(.sidebar-main):not(.sidebar-component)'),
- sidebarMainDesktopToggler = $('.sidebar-main-toggle'),
- sidebarMainMobileToggler = $('.sidebar-mobile-main-toggle'),
- sidebarCollapsedClass = 'sidebar-collapsed',
- sidebarMobileExpandedClass = 'sidebar-mobile-expanded';
- $('#sidebar-main').on('click', function(e) {
- e.preventDefault();
- if (matchMedia('screen and (max-width: 1200px)').matches) {
- sidebarMainElement.toggleClass(sidebarMobileExpandedClass);
- sidebarMainRestElements.removeClass(sidebarMobileExpandedClass);
- } else {
- sidebarMainElement.toggleClass(sidebarCollapsedClass);
- }
- })
- // // On desktop
- // sidebarMainDesktopToggler.on('click', function(e) {
- // e.preventDefault();
- // sidebarMainElement.toggleClass(sidebarCollapsedClass);
- // });
- // On mobile
- sidebarMainMobileToggler.on('click', function(e) {
- e.preventDefault();
- sidebarMainElement.toggleClass(sidebarMobileExpandedClass);
- sidebarMainRestElements.removeClass(sidebarMobileExpandedClass);
- });
- };
- // Toggle secondary sidebar
- const sidebarSecondaryToggle = function() {
- // Elements
- const sidebarSecondaryElement = $('.sidebar-secondary'),
- sidebarSecondaryRestElements = $('.sidebar:not(.sidebar-secondary):not(.sidebar-component)'),
- sidebarSecondaryDesktopToggler = $('.sidebar-secondary-toggle'),
- sidebarSecondaryMobileToggler = $('.sidebar-mobile-secondary-toggle'),
- sidebarCollapsedClass = 'sidebar-collapsed',
- sidebarMobileExpandedClass = 'sidebar-mobile-expanded';
- // On desktop
- sidebarSecondaryDesktopToggler.on('click', function(e) {
- e.preventDefault();
- sidebarSecondaryElement.toggleClass(sidebarCollapsedClass);
- });
- // On mobile
- sidebarSecondaryMobileToggler.on('click', function(e) {
- e.preventDefault();
- sidebarSecondaryElement.toggleClass(sidebarMobileExpandedClass);
- sidebarSecondaryRestElements.removeClass(sidebarMobileExpandedClass);
- });
- };
- // Toggle right sidebar
- const sidebarRightToggle = function() {
- // Elements
- const sidebarRightElement = $('.sidebar-right'),
- sidebarRightRestElements = $('.sidebar:not(.sidebar-right):not(.sidebar-component)'),
- sidebarRightDesktopToggler = $('.sidebar-right-toggle'),
- sidebarRightMobileToggler = $('.sidebar-mobile-right-toggle'),
- sidebarCollapsedClass = 'sidebar-collapsed',
- sidebarMobileExpandedClass = 'sidebar-mobile-expanded';
- $(sidebarRightDesktopToggler).on('click', function(e) {
- e.preventDefault();
- if (matchMedia('screen and (max-width: 1200px)').matches) {
- sidebarRightElement.toggleClass(sidebarMobileExpandedClass);
- sidebarRightRestElements.removeClass(sidebarMobileExpandedClass);
- } else {
- sidebarRightElement.toggleClass(sidebarCollapsedClass);
- }
- });
- // // On desktop
- // sidebarRightDesktopToggler.on('click', function(e) {
- // e.preventDefault();
- // sidebarRightElement.toggleClass(sidebarCollapsedClass);
- // });
- // // On mobile
- // sidebarRightMobileToggler.on('click', function(e) {
- // e.preventDefault();
- // sidebarRightElement.toggleClass(sidebarMobileExpandedClass);
- // sidebarRightRestElements.removeClass(sidebarMobileExpandedClass);
- // });
- };
- // Toggle component sidebar
- const sidebarComponentToggle = function() {
- // Elements
- const sidebarComponentElement = $('.sidebar-component'),
- sidebarComponentMobileToggler = $('.sidebar-mobile-component-toggle'),
- sidebarMobileExpandedClass = 'sidebar-mobile-expanded';
- // Toggle classes
- sidebarComponentMobileToggler.on('click', function(e) {
- e.preventDefault();
- sidebarComponentElement.toggleClass(sidebarMobileExpandedClass);
- });
- };
- // Navigations
- // -------------------------
- // Sidebar navigation
- const navigationSidebar = function() {
- // Define default class names and options
- var navClass = 'nav-sidebar',
- navItemClass = 'nav-item',
- navItemOpenClass = 'nav-item-open',
- navLinkClass = 'nav-link',
- navSubmenuClass = 'nav-group-sub',
- navScrollSpyClass = 'nav-scrollspy',
- navSlidingSpeed = 250;
- // Configure collapsible functionality
- $('.' + navClass + ':not(.' + navScrollSpyClass + ')').each(function() {
- $(this).find('.' + navItemClass).has('.' + navSubmenuClass).children('.' + navItemClass + ' > ' + '.' + navLinkClass).not('.disabled').on('click', function (e) {
- e.preventDefault();
- // Simplify stuff
- var $target = $(this);
- // Collapsible
- if($target.parent('.' + navItemClass).hasClass(navItemOpenClass)) {
- $target.parent('.' + navItemClass).removeClass(navItemOpenClass).children('.' + navSubmenuClass).slideUp(navSlidingSpeed);
- }
- else {
- $target.parent('.' + navItemClass).addClass(navItemOpenClass).children('.' + navSubmenuClass).slideDown(navSlidingSpeed);
- }
- // Accordion
- if ($target.parents('.' + navClass).data('nav-type') == 'accordion') {
- $target.parent('.' + navItemClass).siblings(':has(.' + navSubmenuClass + ')').removeClass(navItemOpenClass).children('.' + navSubmenuClass).slideUp(navSlidingSpeed);
- }
- });
- });
- // Disable click in disabled navigation items
- $(document).on('click', '.' + navClass + ' .disabled', function(e) {
- e.preventDefault();
- });
- };
- // Navbar navigation
- const navigationNavbar = function() {
- // Prevent dropdown from closing on click
- $(document).on('click', '.dropdown-content', function(e) {
- e.stopPropagation();
- });
- // Disabled links
- $('.navbar-nav .disabled a, .nav-item-levels .disabled').on('click', function(e) {
- e.preventDefault();
- e.stopPropagation();
- });
- // Show tabs inside dropdowns
- $('.dropdown-content a[data-toggle="tab"]').on('click', function() {
- $(this).tab('show');
- });
- };
- // Components
- // -------------------------
- // Tooltip
- const componentTooltip = function() {
- $('[data-popup="tooltip"]').tooltip({
- boundary: '.page-content'
- });
- };
- // Popover
- const componentPopover = function() {
- $('[data-popup="popover"]').popover({
- boundary: '.page-content'
- });
- };
- // "Go to top" button
- const componentToTopButton = function() {
- // Elements
- const toTopContainer = $('.content-wrapper'),
- scrollableContainer = $('.content-inner'),
- scrollableDistance = 250;
- // Append only if container exists
- if (scrollableContainer) {
- // Create button
- toTopContainer.append($('<div class="btn-to-top"><button type="button" class="btn btn-dark btn-icon rounded-pill"><i class="icon-arrow-up8"></i></button></div>'));
- // Show and hide on scroll
- const to_top_button = $('.btn-to-top'),
- add_class_on_scroll = function() {
- to_top_button.addClass('btn-to-top-visible');
- },
- remove_class_on_scroll = function() {
- to_top_button.removeClass('btn-to-top-visible');
- };
- scrollableContainer.on('scroll', function() {
- const scrollpos = scrollableContainer.scrollTop();
- if (scrollpos >= scrollableDistance) {
- add_class_on_scroll();
- }
- else {
- remove_class_on_scroll();
- }
- });
- // Scroll to top on click
- $('.btn-to-top .btn').on('click', function() {
- scrollableContainer.scrollTop(0);
- });
- }
- };
- // Card actions
- // -------------------------
- // Reload card (uses BlockUI extension)
- const cardActionReload = function() {
- // Elements
- const buttonElement = $('[data-action=reload]'),
- overlayContainer = '.card',
- overlayClass = 'card-overlay',
- spinnerClass = 'icon-spinner9 spinner text-body',
- overlayAnimationClass = 'card-overlay-fadeout';
- // Configure
- buttonElement.on('click', function(e) {
- e.preventDefault();
- // Create overlay with spinner
- $(this).parents(overlayContainer).append($('<div class="' + overlayClass + '"><i class="' + spinnerClass + '"></i></div>'));
- // Remove overlay after 2.5s, for demo only
- setTimeout(function() {
- $('.' + overlayClass).addClass(overlayAnimationClass).on('animationend animationcancel', function() {
- $(this).remove();
- });
- }, 2500);
- });
- };
- // Collapse card
- const cardActionCollapse = function() {
- // Elements
- const buttonElement = $('[data-action=collapse]'),
- cardContainer = '.card',
- cardCollapsedClass = 'card-collapsed';
- // Configure
- buttonElement.on('click', function(e) {
- e.preventDefault();
- const parentContainer = $(this).parents('.card'),
- collapsibleContainer = parentContainer.find('> .collapse');
- if (parentContainer.hasClass(cardCollapsedClass)) {
- parentContainer.removeClass(cardCollapsedClass);
- collapsibleContainer.collapse('show');
- }
- else {
- parentContainer.addClass(cardCollapsedClass);
- collapsibleContainer.collapse('hide');
- }
- });
- };
- // Remove card
- const cardActionRemove = function() {
- // Elements
- const buttonElement = $('[data-action=remove]'),
- cardContainer = '.card';
- // Configure
- buttonElement.on('click', function(e) {
- e.preventDefault();
- $(this).parents(cardContainer).slideUp(150);
- });
- };
- // Card fullscreen mode
- const cardActionFullscreen = function() {
- // Elements
- const buttonElement = '[data-action=fullscreen]',
- buttonClass = 'list-icons-item',
- buttonContainerClass = 'list-icons',
- cardFullscreenClass = 'card-fullscreen',
- collapsedClass = 'collapsed-in-fullscreen',
- scrollableContainerClass = 'content-inner',
- fullscreenAttr = 'data-fullscreen';
- // Configure
- $(buttonElement).on('click', function(e) {
- e.preventDefault();
- const button = $(this);
- // Get closest card container
- const cardFullscreen = button.parents('.card');
- // Toggle required classes
- cardFullscreen.toggleClass(cardFullscreenClass);
- // Toggle classes depending on state
- if (!cardFullscreen.hasClass(cardFullscreenClass)) {
- button.removeAttr(fullscreenAttr);
- cardFullscreen.find('.' + collapsedClass).removeClass('show');
- $('.' + scrollableContainerClass).removeClass('overflow-hidden');
- button.parents('.' + buttonContainerClass).find('.' + buttonClass + ':not(' + buttonElement + ')').removeClass('d-none');
- }
- else {
- button.attr(fullscreenAttr, 'active');
- cardFullscreen.removeAttr('style');
- cardFullscreen.find('.collapse:not(.show)').addClass('show ' + collapsedClass);
- $('.' + scrollableContainerClass).addClass('overflow-hidden');
- button.parents('.' + buttonContainerClass).find('.' + buttonClass + ':not(' + buttonElement + ')').addClass('d-none');
- }
- });
- };
- // Misc
- // -------------------------
- // Re-declare dropdown boundary for app container
- const dropdownMenus = function() {
- $.fn.dropdown.Constructor.Default.boundary = '.page-content';
- };
- // Dropdown submenus. Trigger on click
- const dropdownSubmenu = function() {
- // All parent levels require .dropdown-toggle class
- $('.dropdown-menu').find('.dropdown-submenu').not('.disabled').find('.dropdown-toggle').on('click', function(e) {
- e.stopPropagation();
- e.preventDefault();
- const button = $(this);
- // Remove "show" class in all siblings
- button.parent().siblings().removeClass('show').find('.show').removeClass('show');
- // Toggle submenu
- button.parent().toggleClass('show').children('.dropdown-menu').toggleClass('show');
- // Hide all levels when parent dropdown is closed
- button.parents('.show').on('hidden.bs.dropdown', function(e) {
- $('.dropdown-submenu .show, .dropdown-submenu.show').removeClass('show');
- });
- });
- };
- // Header elements toggler
- const componentHeaderElements = function() {
- // Toggle visible state of header elements
- $('.header-elements-toggle').on('click', function(e) {
- e.preventDefault();
- $(this).parents('[class*=header-elements-]:not(.header-elements-toggle)').find('.header-elements').toggleClass('d-none');
- });
- // Toggle visible state of footer elements
- $('.footer-elements-toggle').on('click', function(e) {
- e.preventDefault();
- $(this).parents('.card-footer').find('.footer-elements').toggleClass('d-none');
- });
- };
- //
- // Return objects assigned to module
- //
- return {
- // Disable transitions before page is fully loaded
- initBeforeLoad: function() {
- detectOS();
- transitionsDisabled();
- },
- // Enable transitions when page is fully loaded
- initAfterLoad: function() {
- transitionsEnabled();
- },
- // Initialize all components
- initComponents: function() {
- componentTooltip();
- componentPopover();
- componentToTopButton();
- componentHeaderElements();
- },
- // Initialize all sidebars
- initSidebars: function() {
- sidebarMainResize();
- sidebarMainToggle();
- sidebarSecondaryToggle();
- sidebarRightToggle();
- sidebarComponentToggle();
- },
- // Initialize all navigations
- initNavigations: function() {
- navigationSidebar();
- navigationNavbar();
- },
- // Initialize all card actions
- initCardActions: function() {
- cardActionReload();
- cardActionCollapse();
- cardActionRemove();
- cardActionFullscreen();
- },
- // Dropdown submenu
- initDropdowns: function() {
- dropdownMenus();
- dropdownSubmenu();
- },
- // Initialize core
- initCore: function() {
- App.initBeforeLoad();
- App.initSidebars();
- App.initNavigations();
- App.initComponents();
- App.initCardActions();
- App.initDropdowns();
- }
- }
- }();
- // Initialize module
- // ------------------------------
- // When content is loaded
- document.addEventListener('DOMContentLoaded', function() {
- App.initCore();
- });
- // When page is fully loaded
- window.addEventListener('load', function() {
- App.initAfterLoad();
- });
|