- Fixed critical security vulnerability with incorrect capability checks - Fixed hardcoded redirect path from /community-login/ to /training-login/ - Moved dashboard shortcode registration to centralized location - Fixed duplicate class loading with proper singleton checks - Fixed incorrect edit URLs in dashboard - Removed debug HTML comments from production templates - Moved inline CSS to external stylesheets for better maintainability - Added caching mechanism for dashboard statistics queries (1 hour cache) - Implemented pagination JavaScript handlers for AJAX navigation - Added comprehensive error handling and logging throughout - Fixed role-based access control (checking roles not capabilities) - Improved performance with cached database queries
321 lines
No EOL
11 KiB
JavaScript
321 lines
No EOL
11 KiB
JavaScript
/**
|
|
* HVAC Menu System JavaScript
|
|
* Handle dropdown interactions and mobile menu behavior
|
|
*/
|
|
|
|
jQuery(function($) {
|
|
'use strict';
|
|
|
|
// COMPLETELY DISABLED SYSTEM - DO NOT USE
|
|
console.log('HVAC Menu: OLD SYSTEM COMPLETELY DISABLED - Use hvac-navigation-robust.js instead');
|
|
return; // EXIT IMMEDIATELY
|
|
|
|
// Check if jQuery is available
|
|
if (typeof jQuery === 'undefined') {
|
|
console.error('HVAC Menu: jQuery is not available');
|
|
return;
|
|
}
|
|
|
|
console.log('HVAC Menu: jQuery loaded, version:', $.fn.jquery);
|
|
|
|
/**
|
|
* Initialize menu system - DISABLED: Replaced by hvac-navigation-robust.js
|
|
*/
|
|
function initHVACMenu() {
|
|
// COMPLETELY DISABLED to prevent conflicts with hvac-navigation-robust.js
|
|
console.log('HVAC Menu: DISABLED - All functionality moved to hvac-navigation-robust.js');
|
|
return;
|
|
|
|
const $menu = $('.hvac-trainer-menu');
|
|
|
|
if (!$menu.length) {
|
|
console.log('HVAC Menu: No menu found with class .hvac-trainer-menu');
|
|
return;
|
|
}
|
|
|
|
console.log('HVAC Menu: Menu found, setting up handlers');
|
|
|
|
// Handle hamburger menu toggle
|
|
handleHamburgerMenu();
|
|
|
|
// Handle dropdown toggles
|
|
handleDropdownToggles($menu);
|
|
|
|
// Handle outside clicks to close dropdowns
|
|
handleOutsideClicks($menu);
|
|
|
|
// Handle keyboard navigation
|
|
handleKeyboardNavigation($menu);
|
|
|
|
// Highlight current page
|
|
highlightCurrentPage($menu);
|
|
}
|
|
|
|
/**
|
|
* Handle hamburger menu toggle
|
|
*/
|
|
function handleHamburgerMenu() {
|
|
// Check if robust navigation has taken control
|
|
if (window.hvacRobustNavigationActive) {
|
|
console.log('HVAC Menu: Robust navigation active, skipping original hamburger setup');
|
|
return;
|
|
}
|
|
|
|
const $hamburger = $('#hvac-hamburger-menu');
|
|
const $menu = $('#hvac-trainer-menu');
|
|
|
|
if (!$hamburger.length || !$menu.length) {
|
|
console.log('HVAC Menu: Hamburger or menu not found');
|
|
return;
|
|
}
|
|
|
|
console.log('HVAC Menu: Setting up hamburger menu', $hamburger.length, $menu.length);
|
|
|
|
// Toggle menu on hamburger click
|
|
$hamburger.on('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
console.log('HVAC Menu: Hamburger clicked');
|
|
|
|
const isActive = $menu.hasClass('active');
|
|
|
|
if (isActive) {
|
|
$menu.removeClass('active');
|
|
$hamburger.removeClass('active');
|
|
$hamburger.attr('aria-expanded', 'false');
|
|
} else {
|
|
$menu.addClass('active');
|
|
$hamburger.addClass('active');
|
|
$hamburger.attr('aria-expanded', 'true');
|
|
}
|
|
});
|
|
|
|
// Close menu when clicking outside on mobile
|
|
$(document).on('click.hvacMobileMenu', function(e) {
|
|
if ($(window).width() <= 992) {
|
|
if (!$(e.target).closest('.hvac-trainer-nav').length) {
|
|
$menu.removeClass('active');
|
|
$hamburger.removeClass('active');
|
|
$hamburger.attr('aria-expanded', 'false');
|
|
}
|
|
}
|
|
});
|
|
|
|
// Close menu on window resize if needed
|
|
$(window).on('resize.hvacMobileMenu', function() {
|
|
if ($(window).width() > 992) {
|
|
$menu.removeClass('active');
|
|
$hamburger.removeClass('active');
|
|
$hamburger.attr('aria-expanded', 'false');
|
|
}
|
|
});
|
|
|
|
// Close menu when ESC is pressed
|
|
$(document).on('keydown.hvacMobileMenu', function(e) {
|
|
if (e.which === 27 && $menu.hasClass('active')) {
|
|
$menu.removeClass('active');
|
|
$hamburger.removeClass('active');
|
|
$hamburger.attr('aria-expanded', 'false');
|
|
$hamburger.focus();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle dropdown toggle clicks
|
|
*/
|
|
function handleDropdownToggles($menu) {
|
|
$menu.find('.menu-toggle').on('click', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
const $menuItem = $(this).closest('.menu-item');
|
|
const $parentMenu = $menuItem.closest('.hvac-trainer-menu, .sub-menu');
|
|
|
|
// Close other open menus at the same level
|
|
$parentMenu.find('> .menu-item.has-children.open').not($menuItem).removeClass('open');
|
|
|
|
// Toggle current menu
|
|
$menuItem.toggleClass('open');
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle clicks outside menu to close dropdowns
|
|
*/
|
|
function handleOutsideClicks($menu) {
|
|
$(document).on('click.hvacMenu', function(e) {
|
|
if (!$(e.target).closest('.hvac-trainer-menu-wrapper').length) {
|
|
$menu.find('.menu-item.has-children.open').removeClass('open');
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Handle keyboard navigation
|
|
*/
|
|
function handleKeyboardNavigation($menu) {
|
|
$menu.find('a, .menu-toggle').on('keydown', function(e) {
|
|
const $current = $(this);
|
|
const $menuItem = $current.closest('.menu-item');
|
|
|
|
switch(e.which) {
|
|
case 13: // Enter
|
|
if ($current.hasClass('menu-toggle')) {
|
|
e.preventDefault();
|
|
$current.click();
|
|
}
|
|
break;
|
|
|
|
case 27: // Escape
|
|
$menu.find('.menu-item.has-children.open').removeClass('open');
|
|
$current.blur();
|
|
break;
|
|
|
|
case 37: // Left arrow
|
|
if ($menuItem.closest('.sub-menu').length) {
|
|
e.preventDefault();
|
|
$menuItem.closest('.has-children').removeClass('open');
|
|
$menuItem.closest('.has-children').find('> .menu-toggle, > a').focus();
|
|
}
|
|
break;
|
|
|
|
case 39: // Right arrow
|
|
if ($menuItem.hasClass('has-children')) {
|
|
e.preventDefault();
|
|
$menuItem.addClass('open');
|
|
$menuItem.find('.sub-menu > .menu-item:first-child > a').focus();
|
|
}
|
|
break;
|
|
|
|
case 38: // Up arrow
|
|
e.preventDefault();
|
|
navigateVertically($current, 'up');
|
|
break;
|
|
|
|
case 40: // Down arrow
|
|
e.preventDefault();
|
|
navigateVertically($current, 'down');
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Navigate vertically through menu items
|
|
*/
|
|
function navigateVertically($current, direction) {
|
|
const $menuItem = $current.closest('.menu-item');
|
|
const $parentMenu = $menuItem.closest('.hvac-trainer-menu, .sub-menu');
|
|
const $siblings = $parentMenu.find('> .menu-item');
|
|
const currentIndex = $siblings.index($menuItem);
|
|
|
|
let targetIndex;
|
|
if (direction === 'down') {
|
|
targetIndex = currentIndex + 1;
|
|
if (targetIndex >= $siblings.length) targetIndex = 0;
|
|
} else {
|
|
targetIndex = currentIndex - 1;
|
|
if (targetIndex < 0) targetIndex = $siblings.length - 1;
|
|
}
|
|
|
|
const $target = $siblings.eq(targetIndex);
|
|
$target.find('> a, > .menu-toggle').focus();
|
|
}
|
|
|
|
/**
|
|
* Highlight current page in menu
|
|
*/
|
|
function highlightCurrentPage($menu) {
|
|
const currentUrl = window.location.pathname;
|
|
|
|
$menu.find('a').each(function() {
|
|
const $link = $(this);
|
|
const linkUrl = $link.attr('href');
|
|
|
|
if (linkUrl && linkUrl !== '#') {
|
|
const linkPath = linkUrl.replace(window.location.origin, '');
|
|
|
|
if (currentUrl === linkPath ||
|
|
(linkPath !== '/' && currentUrl.indexOf(linkPath) === 0)) {
|
|
$link.closest('.menu-item').addClass('current-menu-item');
|
|
|
|
// Also mark parent items
|
|
$link.closest('.sub-menu').closest('.menu-item').addClass('current-menu-parent');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Clean up event handlers
|
|
*/
|
|
function cleanupHVACMenu() {
|
|
$(document).off('click.hvacMenu');
|
|
$(document).off('click.hvacMobileMenu');
|
|
$(document).off('keydown.hvacMobileMenu');
|
|
$(window).off('resize.hvacMobileMenu');
|
|
}
|
|
|
|
// Initialize when DOM is ready with multiple fallback mechanisms
|
|
$(document).ready(function() {
|
|
console.log('HVAC Menu: Document ready, jQuery version:', $.fn.jquery);
|
|
initHVACMenu();
|
|
});
|
|
|
|
// Additional fallback initialization using native DOM events
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
console.log('HVAC Menu: DOMContentLoaded fallback triggered');
|
|
// Only initialize if not already done
|
|
if (typeof jQuery !== 'undefined' && $('#hvac-hamburger-menu').length > 0) {
|
|
const $hamburger = $('#hvac-hamburger-menu');
|
|
const events = jQuery._data($hamburger[0], 'events');
|
|
const hasClickHandler = events && events.click && events.click.length > 0;
|
|
|
|
if (!hasClickHandler) {
|
|
console.log('HVAC Menu: No click handlers found, initializing via fallback');
|
|
initHVACMenu();
|
|
} else {
|
|
console.log('HVAC Menu: Click handlers already attached, skipping fallback init');
|
|
}
|
|
}
|
|
});
|
|
|
|
// Final safety net: Initialize after a short delay if still not initialized
|
|
setTimeout(function() {
|
|
if (typeof jQuery !== 'undefined' && $('#hvac-hamburger-menu').length > 0) {
|
|
const $hamburger = $('#hvac-hamburger-menu');
|
|
const events = jQuery._data($hamburger[0], 'events');
|
|
const hasClickHandler = events && events.click && events.click.length > 0;
|
|
|
|
if (!hasClickHandler) {
|
|
console.log('HVAC Menu: Final safety net initialization');
|
|
initHVACMenu();
|
|
}
|
|
}
|
|
}, 500);
|
|
|
|
// Immediate initialization attempt (runs right away)
|
|
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
|
setTimeout(function() {
|
|
if (typeof jQuery !== 'undefined' && $('#hvac-hamburger-menu').length > 0) {
|
|
const $hamburger = $('#hvac-hamburger-menu');
|
|
const events = jQuery._data ? jQuery._data($hamburger[0], 'events') : null;
|
|
const hasClickHandler = events && events.click && events.click.length > 0;
|
|
|
|
if (!hasClickHandler) {
|
|
console.log('HVAC Menu: Immediate initialization (DOM ready)');
|
|
initHVACMenu();
|
|
}
|
|
}
|
|
}, 100);
|
|
}
|
|
|
|
// Reinitialize on AJAX content updates
|
|
$(document).on('hvac-content-updated', function() {
|
|
cleanupHVACMenu();
|
|
initHVACMenu();
|
|
});
|
|
|
|
}); |