/** * HVAC Mobile Responsive JavaScript * * Provides enhanced mobile functionality including: * - Collapsible form sections * - Mobile navigation toggle * - Touch-friendly interactions * - Responsive table enhancements * * @version 1.0.0 * @author HVAC Community Events Plugin */ (function($) { 'use strict'; // Wait for DOM to be ready $(document).ready(function() { initMobileResponsive(); }); /** * Initialize all mobile responsive functionality */ function initMobileResponsive() { setupCollapsibleFormSections(); setupMobileNavigation(); setupTableResponsiveness(); setupTouchEnhancements(); setupMobileModalHandling(); } /** * Setup collapsible form sections for registration forms */ function setupCollapsibleFormSections() { // Only run on screens smaller than 768px if (window.innerWidth > 768) { return; } // Convert existing form sections to collapsible var $formContainer = $('.hvac-registration-form-container, .hvac-trainer-registration-page'); if ($formContainer.length === 0) { return; } // Find form sections by common headings $formContainer.find('h2, h3').each(function(index) { var $heading = $(this); var $section = $('
'); var $header = $(''); var $content = $(''); var $toggle = $('▼'); // Clone heading content $header.html($heading.html()).append($toggle); // Find content until next heading var $nextElements = $heading.nextUntil('h2, h3'); if ($nextElements.length === 0) { $nextElements = $heading.nextAll(); } // Move content to collapsible section $content.append($nextElements.clone()); $nextElements.remove(); // Build collapsible section $section.append($header, $content); $heading.replaceWith($section); // Collapse all sections except the first one if (index > 0) { $section.addClass('collapsed'); } }); // Add click handlers for collapsible sections $(document).on('click', '.hvac-registration-section-header', function() { var $section = $(this).parent(); $section.toggleClass('collapsed'); // Smooth height animation var $content = $section.find('.hvac-registration-section-content'); if ($section.hasClass('collapsed')) { $content.slideUp(300); } else { $content.slideDown(300); } }); } /** * Setup mobile navigation toggle functionality */ function setupMobileNavigation() { // Only run on mobile screens if (window.innerWidth > 768) { return; } var $navigation = $('.hvac-trainer-navigation'); if ($navigation.length === 0) { return; } // Create mobile menu toggle if it doesn't exist if ($navigation.find('.hvac-mobile-menu-toggle').length === 0) { var $toggle = $(''); $navigation.prepend($toggle); // Wrap existing menu in mobile container var $menu = $navigation.find('ul, nav').first(); if ($menu.length > 0) { $menu.wrap(''); } } // Toggle functionality $(document).on('click', '.hvac-mobile-menu-toggle', function() { var $button = $(this); var $menu = $navigation.find('.hvac-trainer-nav-menu'); $button.toggleClass('active'); $menu.toggleClass('active'); // Update ARIA attributes var isExpanded = $button.hasClass('active'); $button.attr('aria-expanded', isExpanded); }); // Setup submenu toggles $navigation.find('li').has('ul').addClass('has-submenu'); $(document).on('click', '.has-submenu > a', function(e) { if (window.innerWidth <= 768) { e.preventDefault(); var $item = $(this).parent(); $item.toggleClass('active'); $item.find('.submenu, ul').first().slideToggle(200); } }); // Close mobile menu when clicking outside $(document).on('click', function(e) { if (window.innerWidth <= 768) { if (!$(e.target).closest('.hvac-trainer-navigation').length) { $('.hvac-mobile-menu-toggle').removeClass('active'); $('.hvac-trainer-nav-menu').removeClass('active'); } } }); } /** * Enhance table responsiveness with JavaScript */ function setupTableResponsiveness() { // Add data labels to table cells for mobile card layout $('.events-table, .hvac-certificate-table').each(function() { var $table = $(this); var $headers = $table.find('th'); $table.find('tbody tr').each(function() { $(this).find('td').each(function(index) { var $cell = $(this); var $header = $headers.eq(index); if ($header.length > 0) { $cell.attr('data-label', $header.text()); } }); }); }); // Add horizontal scrolling indicators for tables that overflow function addScrollIndicators() { $('.hvac-events-table-wrapper, .hvac-certificate-table-wrapper').each(function() { var $wrapper = $(this); var $table = $wrapper.find('table'); if ($table.length > 0) { var wrapperWidth = $wrapper.width(); var tableWidth = $table.width(); if (tableWidth > wrapperWidth) { $wrapper.addClass('has-horizontal-scroll'); } else { $wrapper.removeClass('has-horizontal-scroll'); } } }); } // Check on load and resize addScrollIndicators(); $(window).on('resize', debounce(addScrollIndicators, 250)); } /** * Setup touch enhancements for mobile devices */ function setupTouchEnhancements() { // Add touch feedback for buttons $('.hvac-button, .hvac-form-submit, button, input[type="submit"]').each(function() { $(this).addClass('hvac-touch-target'); }); // Improve touch scrolling for modal content if ('ontouchstart' in window) { $('.hvac-modal-content, .hvac-popup-content').css({ '-webkit-overflow-scrolling': 'touch', 'overflow-scrolling': 'touch' }); } // Add touch feedback for interactive elements $(document).on('touchstart', '.hvac-touch-target', function() { $(this).addClass('hvac-touch-active'); }); $(document).on('touchend touchcancel', '.hvac-touch-target', function() { var $this = $(this); setTimeout(function() { $this.removeClass('hvac-touch-active'); }, 150); }); } /** * Setup mobile modal handling */ function setupMobileModalHandling() { // Prevent body scrolling when modal is open on mobile $(document).on('show', '.hvac-modal, .hvac-popup', function() { if (window.innerWidth <= 768) { $('body').addClass('hvac-modal-open'); } }); $(document).on('hide', '.hvac-modal, .hvac-popup', function() { $('body').removeClass('hvac-modal-open'); }); // Close modal when tapping backdrop on mobile $(document).on('click', '.hvac-modal, .hvac-popup', function(e) { if (e.target === this && window.innerWidth <= 768) { $(this).trigger('hide'); } }); // Swipe to close functionality for mobile if ('ontouchstart' in window) { setupSwipeToClose(); } } /** * Setup swipe to close functionality for mobile modals */ function setupSwipeToClose() { var startY = 0; var currentY = 0; var isDragging = false; $(document).on('touchstart', '.hvac-modal, .hvac-popup', function(e) { if ($(e.target).is('.hvac-modal, .hvac-popup')) { startY = e.originalEvent.touches[0].pageY; isDragging = true; } }); $(document).on('touchmove', '.hvac-modal, .hvac-popup', function(e) { if (!isDragging) return; currentY = e.originalEvent.touches[0].pageY; var deltaY = currentY - startY; // Add visual feedback for swipe gesture if (Math.abs(deltaY) > 50) { $(this).addClass('hvac-swipe-feedback'); } }); $(document).on('touchend', '.hvac-modal, .hvac-popup', function(e) { if (!isDragging) return; var deltaY = currentY - startY; $(this).removeClass('hvac-swipe-feedback'); // Close modal if swiped down significantly if (deltaY > 100) { $(this).trigger('hide'); } isDragging = false; }); } /** * Handle window resize events */ $(window).on('resize', debounce(function() { // Re-initialize mobile features when crossing breakpoints var width = window.innerWidth; if (width > 768) { // Desktop: Clean up mobile-specific modifications $('.hvac-registration-section').removeClass('collapsed'); $('.hvac-trainer-nav-menu').removeClass('active'); $('.hvac-mobile-menu-toggle').removeClass('active'); } else { // Mobile: Re-initialize if needed setupMobileNavigation(); } }, 250)); /** * Debounce utility function */ function debounce(func, wait) { var timeout; return function executedFunction() { var context = this; var args = arguments; var later = function() { timeout = null; func.apply(context, args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } /** * Utility function to detect touch devices */ function isTouchDevice() { return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; } /** * Add body class for touch devices */ if (isTouchDevice()) { $('body').addClass('hvac-touch-device'); } })(jQuery);