upskill-event-manager/assets/js/hvac-trainer-navigation.js
bengizmo 70b78a069f feat: Add navigation menu system and breadcrumb functionality
- Implemented comprehensive trainer navigation system:
  * Horizontal and vertical navigation layouts
  * Multi-level menu with dropdowns for Events, Venues, Organizers, Profile
  * Responsive mobile navigation with hamburger menu
  * Keyboard navigation support (Arrow keys, Enter, Escape)
  * Active page highlighting
  * Master trainer menu items for users with appropriate role

- Created breadcrumb system:
  * Automatic breadcrumb generation based on URL structure
  * Shortcode support [hvac_breadcrumbs]
  * SEO-friendly with structured data (Schema.org)
  * Multiple style options (default, pills, arrows)
  * Responsive design

- Technical implementation:
  * HVAC_Trainer_Navigation class for menu management
  * HVAC_Breadcrumbs class for breadcrumb generation
  * CSS for both navigation and breadcrumbs
  * JavaScript for interactive menu behaviors
  * Template part for easy inclusion

Navigation provides easy access to all trainer features and improves UX.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 16:45:58 -03:00

257 lines
No EOL
8.2 KiB
JavaScript

/**
* HVAC Trainer Navigation JavaScript
*
* @package HVAC_Community_Events
* @version 2.0.0
*/
jQuery(document).ready(function($) {
// Cache DOM elements
const $nav = $('.hvac-trainer-nav');
const $mobileToggle = $('.hvac-nav-mobile-toggle');
const $body = $('body');
// Initialize navigation
function initNavigation() {
// Handle mobile toggle
if ($mobileToggle.length) {
$mobileToggle.on('click', function(e) {
e.preventDefault();
toggleMobileNav();
});
}
// Handle submenu behavior based on data attribute
const submenuBehavior = $nav.data('submenu');
if (submenuBehavior === 'click') {
initClickSubmenus();
} else if (submenuBehavior === 'hover') {
initHoverSubmenus();
}
// Handle keyboard navigation
initKeyboardNav();
// Handle responsive behavior
initResponsive();
}
// Toggle mobile navigation
function toggleMobileNav() {
$body.toggleClass('hvac-nav-mobile-open');
// Update aria attributes
const isOpen = $body.hasClass('hvac-nav-mobile-open');
$mobileToggle.attr('aria-expanded', isOpen);
// Prevent body scroll when mobile nav is open
if (isOpen) {
$body.css('overflow', 'hidden');
} else {
$body.css('overflow', '');
}
}
// Initialize click-based submenus
function initClickSubmenus() {
$('.hvac-nav-has-submenu > .hvac-nav-link').on('click', function(e) {
const $link = $(this);
const href = $link.attr('href');
// If link is just '#', prevent default and toggle submenu
if (href === '#') {
e.preventDefault();
toggleSubmenu($link.parent());
}
});
// Close submenus when clicking outside
$(document).on('click', function(e) {
if (!$(e.target).closest('.hvac-nav-has-submenu').length) {
closeAllSubmenus();
}
});
}
// Initialize hover-based submenus
function initHoverSubmenus() {
// Add hover intent to prevent accidental triggers
let hoverTimeout;
$('.hvac-nav-has-submenu').on('mouseenter', function() {
const $item = $(this);
clearTimeout(hoverTimeout);
hoverTimeout = setTimeout(function() {
openSubmenu($item);
}, 200);
}).on('mouseleave', function() {
const $item = $(this);
clearTimeout(hoverTimeout);
hoverTimeout = setTimeout(function() {
closeSubmenu($item);
}, 300);
});
}
// Toggle submenu
function toggleSubmenu($item) {
if ($item.hasClass('hvac-nav-open')) {
closeSubmenu($item);
} else {
// Close other submenus first
closeAllSubmenus();
openSubmenu($item);
}
}
// Open submenu
function openSubmenu($item) {
$item.addClass('hvac-nav-open');
$item.find('.hvac-nav-submenu').stop(true, true).slideDown(200);
// Update aria attributes
$item.find('> .hvac-nav-link').attr('aria-expanded', 'true');
}
// Close submenu
function closeSubmenu($item) {
$item.removeClass('hvac-nav-open');
$item.find('.hvac-nav-submenu').stop(true, true).slideUp(200);
// Update aria attributes
$item.find('> .hvac-nav-link').attr('aria-expanded', 'false');
}
// Close all submenus
function closeAllSubmenus() {
$('.hvac-nav-has-submenu').each(function() {
closeSubmenu($(this));
});
}
// Initialize keyboard navigation
function initKeyboardNav() {
$('.hvac-nav-link, .hvac-nav-sublink').on('keydown', function(e) {
const $link = $(this);
const $item = $link.parent();
switch(e.key) {
case 'Enter':
case ' ':
if ($item.hasClass('hvac-nav-has-submenu') && $link.attr('href') === '#') {
e.preventDefault();
toggleSubmenu($item);
}
break;
case 'Escape':
if ($item.closest('.hvac-nav-submenu').length) {
e.preventDefault();
const $parentItem = $item.closest('.hvac-nav-has-submenu');
closeSubmenu($parentItem);
$parentItem.find('> .hvac-nav-link').focus();
}
break;
case 'ArrowDown':
e.preventDefault();
focusNextMenuItem($link);
break;
case 'ArrowUp':
e.preventDefault();
focusPrevMenuItem($link);
break;
case 'ArrowRight':
if ($item.hasClass('hvac-nav-has-submenu')) {
e.preventDefault();
openSubmenu($item);
$item.find('.hvac-nav-sublink').first().focus();
}
break;
case 'ArrowLeft':
if ($item.closest('.hvac-nav-submenu').length) {
e.preventDefault();
const $parentItem = $item.closest('.hvac-nav-has-submenu');
closeSubmenu($parentItem);
$parentItem.find('> .hvac-nav-link').focus();
}
break;
}
});
}
// Focus next menu item
function focusNextMenuItem($currentLink) {
const $allLinks = $('.hvac-nav-link:visible, .hvac-nav-sublink:visible');
const currentIndex = $allLinks.index($currentLink);
if (currentIndex < $allLinks.length - 1) {
$allLinks.eq(currentIndex + 1).focus();
}
}
// Focus previous menu item
function focusPrevMenuItem($currentLink) {
const $allLinks = $('.hvac-nav-link:visible, .hvac-nav-sublink:visible');
const currentIndex = $allLinks.index($currentLink);
if (currentIndex > 0) {
$allLinks.eq(currentIndex - 1).focus();
}
}
// Initialize responsive behavior
function initResponsive() {
let windowWidth = $(window).width();
$(window).on('resize', function() {
const newWidth = $(window).width();
// Check if we've crossed the mobile breakpoint
if ((windowWidth > 768 && newWidth <= 768) || (windowWidth <= 768 && newWidth > 768)) {
// Reset mobile nav state
$body.removeClass('hvac-nav-mobile-open');
$body.css('overflow', '');
closeAllSubmenus();
}
windowWidth = newWidth;
});
}
// Highlight current page in navigation
function highlightCurrentPage() {
const currentPath = window.location.pathname;
// Remove any existing active classes
$('.hvac-nav-active').removeClass('hvac-nav-active');
// Find matching link
$('.hvac-nav-link, .hvac-nav-sublink').each(function() {
const $link = $(this);
const href = $link.attr('href');
if (href && href !== '#' && currentPath.indexOf(href) !== -1) {
$link.parent().addClass('hvac-nav-active');
// If it's a submenu item, also highlight parent
const $parentItem = $link.closest('.hvac-nav-has-submenu');
if ($parentItem.length) {
$parentItem.addClass('hvac-nav-active');
}
}
});
}
// Initialize everything
if ($nav.length) {
initNavigation();
highlightCurrentPage();
}
});