/** * Find a Trainer Page JavaScript - Safari Compatible Version * Handles filtering, modals, and AJAX interactions * ES5 compatible for Safari browser support * * @package HVAC_Plugin * @since 1.0.0 */ (function($) { 'use strict'; // Cache DOM elements var $filterModal, $trainerModal, $contactForm; var currentFilter = ''; var activeFilters = {}; var currentPage = 1; var isLoading = false; // Initialize on document ready $(document).ready(function() { initializeElements(); bindEvents(); // Handle direct profile URL access handleDirectProfileAccess(); // Enable MapGeo interaction handling (only if not showing direct profile) if (!hvac_find_trainer.show_direct_profile) { preventMapGeoSidebarContent(); interceptMapGeoMarkers(); // Additional MapGeo integration after map loads setTimeout(function() { initializeMapGeoEvents(); }, 2000); // Give MapGeo time to initialize } }); /** * Initialize cached elements */ function initializeElements() { $filterModal = $('#hvac-filter-modal'); $trainerModal = $('#hvac-trainer-modal'); $contactForm = $('#hvac-contact-form'); } /** * Prevent MapGeo from displaying content in its sidebar * This ensures trainer cards only appear in our Container 5 */ function preventMapGeoSidebarContent() { // Remove any MapGeo sidebar content immediately $('.igm_content_right_1_3').remove(); $('.igm_content_gutter').remove(); // Watch for any dynamic content injection from MapGeo var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes.length) { mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { // Element node // Remove any MapGeo sidebar that gets added if ($(node).hasClass('igm_content_right_1_3') || $(node).hasClass('igm_content_gutter')) { $(node).remove(); } // Also check children $(node).find('.igm_content_right_1_3, .igm_content_gutter').remove(); } }); } }); }); // Observe the map section for changes var mapSection = document.querySelector('.hvac-map-section'); if (mapSection) { observer.observe(mapSection, { childList: true, subtree: true }); } // Also observe the entire page for MapGeo injections observer.observe(document.body, { childList: true, subtree: true }); } /** * Initialize MapGeo-specific event handlers after map loads */ function initializeMapGeoEvents() { console.log('Initializing MapGeo events...'); // Create the main MapGeo handler function // This replaces the early version created in the page template window.hvacMainShowTrainerModal = function(data) { console.log('MapGeo custom action triggered with data:', data); // Method 1: Use profile_id if available (most reliable) var profileId = null; if (data && data.profile_id && data.profile_id.trim() !== '') { profileId = data.profile_id.trim(); } else if (data && data.id && data.id.toString().startsWith('trainer_')) { // Extract profile ID from marker ID format "trainer_123" profileId = data.id.replace('trainer_', ''); } else if (data && data.name && data.name.match(/^\d+$/)) { // Check if name field actually contains the profile ID (common case) profileId = data.name; } else if (data && data.id && data.id.match(/^\d+$/)) { // Check if id field contains just the profile ID number profileId = data.id; } console.log('Extracted profile ID:', profileId); if (profileId) { // Find trainer card by profile ID (most reliable method) var $matchingCard = $('.hvac-trainer-card[data-profile-id="' + profileId + '"]'); if ($matchingCard.length > 0 && !$matchingCard.hasClass('hvac-champion-card')) { console.log('Found matching trainer card by profile ID:', profileId); // Extract trainer data from the card var trainerData = { profile_id: profileId, name: $matchingCard.find('.hvac-trainer-name a, .hvac-trainer-name .hvac-champion-name').text().trim(), city: $matchingCard.find('.hvac-trainer-location').text().split(',')[0], state: $matchingCard.find('.hvac-trainer-location').text().split(',')[1] ? $matchingCard.find('.hvac-trainer-location').text().split(',')[1].trim() : '', certification_type: $matchingCard.find('.hvac-trainer-certification').text(), profile_image: $matchingCard.find('.hvac-trainer-image img:not(.hvac-mq-badge)').attr('src') || '', business_type: 'Independent Contractor', // Mock data event_count: parseInt($matchingCard.data('event-count')) || 0, training_formats: 'In-Person, Virtual', training_locations: 'On-site, Remote', upcoming_events: [] }; // Show the trainer modal showTrainerModal(trainerData); return; // Successfully handled } else if ($matchingCard.length > 0 && $matchingCard.hasClass('hvac-champion-card')) { console.log('Clicked marker is for a Champion, not showing modal'); return; // Champions don't get modals } else { console.warn('No trainer card found for profile ID:', profileId); } } // Fallback Method 2: Try to extract trainer name and match var trainerName = null; // Try various name fields if (data && data.name && data.name.trim() !== '+' && !data.name.match(/^\d+$/)) { trainerName = data.name.trim(); } else if (data && data.title && data.title.trim() !== '+') { trainerName = data.title.trim(); } // Try content field if (!trainerName && data && data.content) { console.log('Trying to extract trainer from content:', data.content); var tempDiv = document.createElement('div'); tempDiv.innerHTML = data.content; var nameElements = tempDiv.querySelectorAll('h4, strong, .trainer-name, [class*="name"]'); if (nameElements.length > 0) { trainerName = nameElements[0].textContent.trim(); } } // Try tooltipContent if (!trainerName && data && data.tooltipContent) { var tempDiv = document.createElement('div'); tempDiv.innerHTML = data.tooltipContent; var strongElements = tempDiv.querySelectorAll('strong'); if (strongElements.length > 0) { trainerName = strongElements[0].textContent.trim(); } } console.log('Extracted trainer name (fallback):', trainerName); if (trainerName && trainerName !== '+') { // Try to find matching trainer by name var $matchingCard = $('.hvac-trainer-card').filter(function() { var cardName = $(this).find('.hvac-trainer-name a, .hvac-trainer-name .hvac-champion-name').text().trim(); return cardName === trainerName; }); // If exact match not found, try partial matching if ($matchingCard.length === 0) { $matchingCard = $('.hvac-trainer-card').filter(function() { var cardName = $(this).find('.hvac-trainer-name a, .hvac-trainer-name .hvac-champion-name').text().trim(); return cardName.toLowerCase().includes(trainerName.toLowerCase()) || trainerName.toLowerCase().includes(cardName.toLowerCase()); }); } if ($matchingCard.length > 0 && !$matchingCard.hasClass('hvac-champion-card')) { console.log('Found matching trainer card by name:', trainerName); // Extract trainer data from the card var trainerData = { profile_id: $matchingCard.data('profile-id'), name: $matchingCard.find('.hvac-trainer-name a, .hvac-trainer-name .hvac-champion-name').text().trim(), city: $matchingCard.find('.hvac-trainer-location').text().split(',')[0], state: $matchingCard.find('.hvac-trainer-location').text().split(',')[1] ? $matchingCard.find('.hvac-trainer-location').text().split(',')[1].trim() : '', certification_type: $matchingCard.find('.hvac-trainer-certification').text(), profile_image: $matchingCard.find('.hvac-trainer-image img:not(.hvac-mq-badge)').attr('src') || '', business_type: 'Independent Contractor', // Mock data event_count: parseInt($matchingCard.data('event-count')) || 0, training_formats: 'In-Person, Virtual', training_locations: 'On-site, Remote', upcoming_events: [] }; // Show the trainer modal showTrainerModal(trainerData); } else if ($matchingCard.length > 0 && $matchingCard.hasClass('hvac-champion-card')) { console.log('Matched trainer is a Champion, not showing modal'); } else { console.warn('No matching trainer found for name:', trainerName); console.log('Available trainers:', $('.hvac-trainer-card .hvac-trainer-name a, .hvac-trainer-card .hvac-trainer-name .hvac-champion-name').map(function() { return $(this).text().trim(); }).get() ); } } else { console.warn('Could not extract valid trainer identifier from MapGeo data:', data); console.log('Available data properties:', data ? Object.keys(data) : []); console.log('Available profile IDs on page:', $('.hvac-trainer-card').map(function() { return $(this).data('profile-id'); }).get() ); } }; // Replace the early function with the main one window.hvacShowTrainerModal = window.hvacMainShowTrainerModal; // Process any queued calls from before the main script loaded if (window.hvacPendingModalCalls && window.hvacPendingModalCalls.length > 0) { console.log('Processing', window.hvacPendingModalCalls.length, 'queued MapGeo calls'); window.hvacPendingModalCalls.forEach(function(data) { window.hvacMainShowTrainerModal(data); }); window.hvacPendingModalCalls = []; // Clear the queue } console.log('MapGeo custom action function created: window.hvacShowTrainerModal'); } /** * Prevent MapGeo from showing content in sidebar (if needed) */ function interceptMapGeoMarkers() { // This function now primarily handles preventing MapGeo sidebar content // The actual marker clicks are handled via the MapGeo custom action: window.hvacShowTrainerModal // Handle any legacy view profile links if they exist in tooltips/popups $(document).on('click', '.hvac-view-profile, .hvac-marker-popup button', function(e) { e.preventDefault(); e.stopPropagation(); var profileId = $(this).data('profile-id'); if (profileId) { // Find the corresponding trainer data from the cards var $trainerCard = $('.hvac-trainer-card[data-profile-id="' + profileId + '"]'); if ($trainerCard.length > 0 && !$trainerCard.hasClass('hvac-champion-card')) { // Get trainer name and trigger the MapGeo custom action var trainerName = $trainerCard.find('.hvac-trainer-name a, .hvac-trainer-name .hvac-champion-name').text().trim(); // Trigger the same function MapGeo would call if (window.hvacShowTrainerModal) { window.hvacShowTrainerModal({ name: trainerName }); } } } }); } /** * Bind all event handlers */ function bindEvents() { // Filter button clicks $('.hvac-filter-btn').on('click', handleFilterClick); // Filter modal apply $('.hvac-filter-apply').on('click', applyFilters); // Clear all filters button $('.hvac-clear-filters').on('click', clearAllFilters); // Trainer profile clicks - using event delegation $(document).on('click', '.hvac-open-profile', handleProfileClick); // Modal close buttons and backdrop clicks $('.hvac-modal-close').on('click', closeModals); // Click on modal backdrop to close $filterModal.on('click', function(e) { if ($(e.target).is('#hvac-filter-modal')) { closeModals(); } }); $trainerModal.on('click', function(e) { if ($(e.target).is('#hvac-trainer-modal')) { closeModals(); } }); // Escape key to close modals $(document).on('keydown', function(e) { if (e.key === 'Escape') { closeModals(); } }); // Search input $('#hvac-trainer-search').on('input', debounce(handleSearch, 500)); // Contact form submission (both modal and direct forms) $contactForm.on('submit', handleContactSubmit); $(document).on('submit', '#hvac-direct-contact-form', handleContactSubmit); // Pagination clicks $(document).on('click', '.hvac-pagination a, .hvac-page-link', handlePagination); // Active filter removal $(document).on('click', '.hvac-active-filter button', removeActiveFilter); } /** * Handle filter button click */ function handleFilterClick(e) { e.preventDefault(); e.stopPropagation(); currentFilter = $(this).data('filter'); // For now, show mock filter options showFilterModal(getMockFilterOptions(currentFilter)); } /** * Get mock filter options (replace with AJAX later) */ function getMockFilterOptions(filterType) { var options = { state: [ {value: 'Alabama', label: 'Alabama'}, {value: 'Alaska', label: 'Alaska'}, {value: 'Arizona', label: 'Arizona'}, {value: 'Arkansas', label: 'Arkansas'}, {value: 'California', label: 'California'}, {value: 'Colorado', label: 'Colorado'}, {value: 'Florida', label: 'Florida'}, {value: 'Georgia', label: 'Georgia'}, {value: 'Illinois', label: 'Illinois'}, {value: 'Michigan', label: 'Michigan'}, {value: 'Minnesota', label: 'Minnesota'}, {value: 'Ohio', label: 'Ohio'}, {value: 'Texas', label: 'Texas'}, {value: 'Wisconsin', label: 'Wisconsin'} ], business_type: [ {value: 'Independent Contractor', label: 'Independent Contractor'}, {value: 'Small Business', label: 'Small Business'}, {value: 'Corporation', label: 'Corporation'}, {value: 'Non-Profit', label: 'Non-Profit'} ], training_format: [ {value: 'In-Person', label: 'In-Person'}, {value: 'Virtual', label: 'Virtual'}, {value: 'Hybrid', label: 'Hybrid'}, {value: 'Self-Paced', label: 'Self-Paced'} ], training_resources: [ {value: 'Video Tutorials', label: 'Video Tutorials'}, {value: 'Written Guides', label: 'Written Guides'}, {value: 'Hands-On Training', label: 'Hands-On Training'}, {value: 'Certification Programs', label: 'Certification Programs'} ] }; return { options: options[filterType] || [] }; } /** * Show filter modal with options */ function showFilterModal(data) { var $modalTitle = $filterModal.find('.hvac-filter-modal-title'); var $modalOptions = $filterModal.find('.hvac-filter-options'); // Set title var title = currentFilter.replace(/_/g, ' '); title = title.charAt(0).toUpperCase() + title.slice(1); $modalTitle.text(title); // Build options HTML var optionsHtml = ''; var currentValues = activeFilters[currentFilter] || []; data.options.forEach(function(option) { var checked = currentValues.indexOf(option.value) !== -1 ? 'checked' : ''; optionsHtml += '