/** * Find a Trainer Page JavaScript * Handles filtering, modals, and AJAX interactions * * @package HVAC_Plugin * @since 1.0.0 */ (function($) { 'use strict'; // Cache DOM elements let $filterModal, $trainerModal, $contactForm; let currentFilter = ''; let activeFilters = {}; let currentPage = 1; let 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'); // CRITICAL: Ensure modals are hidden on initialization if ($filterModal.length) { $filterModal.removeClass('modal-active active show').css({ 'display': 'none', 'visibility': 'hidden', 'opacity': '0' }); } if ($trainerModal.length) { $trainerModal.css('display', 'none'); } } /** * 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 const 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 const 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) let 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) const $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 const 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]?.trim(), certification_type: $matchingCard.find('.hvac-trainer-certification').text(), // Legacy compatibility certifications: [], 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: [] }; // Extract certifications from card badges $matchingCard.find('.hvac-trainer-cert-badge').each(function() { const certText = $(this).text().trim(); if (certText && certText !== 'HVAC Trainer') { trainerData.certifications.push({ type: certText, status: $(this).hasClass('hvac-cert-legacy') ? 'legacy' : 'active' }); } }); // 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 let 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); const tempDiv = document.createElement('div'); tempDiv.innerHTML = data.content; const 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) { const tempDiv = document.createElement('div'); tempDiv.innerHTML = data.tooltipContent; const 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 let $matchingCard = $('.hvac-trainer-card').filter(function() { const 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() { const 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 const 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]?.trim(), certification_type: $matchingCard.find('.hvac-trainer-certification').text(), // Legacy compatibility certifications: [], 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: [] }; // Extract certifications from card badges $matchingCard.find('.hvac-trainer-cert-badge').each(function() { const certText = $(this).text().trim(); if (certText && certText !== 'HVAC Trainer') { trainerData.certifications.push({ type: certText, status: $(this).hasClass('hvac-cert-legacy') ? 'legacy' : 'active' }); } }); // 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:', 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(); const profileId = $(this).data('profile-id'); if (profileId) { // Find the corresponding trainer data from the cards const $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 const 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 - handle both class variations $('.hvac-filter-btn, .hvac-filter-button').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-search-input').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'); // Load real filter options via AJAX loadFilterOptions(currentFilter); } /** * Load filter options via AJAX */ function loadFilterOptions(filterType) { if (isLoading) return; isLoading = true; // Show loading state for filter button $(`.hvac-filter-btn[data-filter="${filterType}"]`).addClass('loading'); $.post(hvac_find_trainer.ajax_url, { action: 'hvac_get_filter_options', filter_type: filterType, nonce: hvac_find_trainer.nonce }) .done(function(response) { if (response.success && response.data.options) { // Convert the different response formats to standard format let options = []; if (filterType === 'business_type') { // Business types have {value, label, count} format options = response.data.options; } else { // States and other simple arrays need to be converted to {value, label} format options = response.data.options.map(function(option) { if (typeof option === 'string') { return {value: option, label: option}; } return option; }); } showFilterModal({options: options}); } else { console.error('Failed to load filter options:', response); // Fallback to empty options showFilterModal({options: []}); } }) .fail(function(xhr, status, error) { console.error('AJAX error loading filter options:', status, error); // Fallback to empty options showFilterModal({options: []}); }) .always(function() { isLoading = false; $(`.hvac-filter-btn[data-filter="${filterType}"]`).removeClass('loading'); }); } /** * Get mock filter options (kept as fallback) */ function getMockFilterOptions(filterType) { const 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) { const $modalTitle = $filterModal.find('.hvac-filter-modal-title'); const $modalOptions = $filterModal.find('.hvac-filter-options'); // Set title let title = currentFilter.replace(/_/g, ' '); title = title.charAt(0).toUpperCase() + title.slice(1); $modalTitle.text(title); // Build options HTML let optionsHtml = ''; const currentValues = activeFilters[currentFilter] || []; data.options.forEach(function(option) { const checked = currentValues.includes(option.value) ? 'checked' : ''; optionsHtml += `
`; }); $modalOptions.html(optionsHtml); // Show modal with proper CSS class and inline style overrides $filterModal.addClass('modal-active'); // Force styles with higher specificity by setting them directly on the element $filterModal[0].style.setProperty('display', 'flex', 'important'); $filterModal[0].style.setProperty('visibility', 'visible', 'important'); $filterModal[0].style.setProperty('opacity', '1', 'important'); } /** * Apply selected filters */ function applyFilters() { const selectedValues = []; $filterModal.find('.hvac-filter-option input:checked').each(function() { selectedValues.push($(this).val()); }); if (selectedValues.length > 0) { activeFilters[currentFilter] = selectedValues; } else { delete activeFilters[currentFilter]; } updateActiveFiltersDisplay(); updateClearButtonVisibility(); currentPage = 1; loadFilteredTrainers(); closeModals(); } /** * Update active filters display */ function updateActiveFiltersDisplay() { const $container = $('.hvac-active-filters'); let html = ''; for (const [filter, values] of Object.entries(activeFilters)) { values.forEach(function(value) { html += `
${value}
`; }); } $container.html(html); } /** * Remove active filter */ function removeActiveFilter(e) { e.preventDefault(); const $filter = $(this).parent(); const filter = $filter.data('filter'); const value = $filter.data('value'); if (activeFilters[filter]) { activeFilters[filter] = activeFilters[filter].filter(v => v !== value); if (activeFilters[filter].length === 0) { delete activeFilters[filter]; } } updateActiveFiltersDisplay(); updateClearButtonVisibility(); currentPage = 1; loadFilteredTrainers(); } /** * Handle trainer profile click */ function handleProfileClick(e) { e.preventDefault(); e.stopPropagation(); const $card = $(this).closest('.hvac-trainer-card'); // Don't allow clicks on Champion cards if ($card.hasClass('hvac-champion-card')) { return false; } const profileId = $(this).data('profile-id'); // Get trainer data from the card const trainerData = { profile_id: profileId, name: $card.find('.hvac-trainer-name a').text(), city: $card.find('.hvac-trainer-location').text().split(',')[0], state: $card.find('.hvac-trainer-location').text().split(',')[1]?.trim(), certification_type: $card.find('.hvac-trainer-certification').text(), // Legacy field for compatibility certifications: [], // Will be populated from card badges profile_image: $card.find('.hvac-trainer-image img:not(.hvac-mq-badge)').attr('src') || '', business_type: 'Independent Contractor', // Mock data event_count: parseInt($card.data('event-count')) || 0, // Real event count from data attribute training_formats: 'In-Person, Virtual', training_locations: 'On-site, Remote', upcoming_events: [] // Mock empty events }; // Extract certifications from card badges $card.find('.hvac-trainer-cert-badge').each(function() { const certText = $(this).text().trim(); if (certText && certText !== 'HVAC Trainer') { trainerData.certifications.push({ type: certText, status: $(this).hasClass('hvac-cert-legacy') ? 'legacy' : 'active' }); } }); showTrainerModal(trainerData); } /** * Show trainer profile modal * Made global so MapGeo can access it */ function showTrainerModal(trainer) { // Update modal title $trainerModal.find('.hvac-modal-title').text(trainer.name); // Update profile image const $imgContainer = $trainerModal.find('.hvac-modal-image'); let imageHtml = ''; if (trainer.profile_image) { imageHtml = `${trainer.name}`; } else { imageHtml = '
'; } // Add mQ badge overlay for certified trainers let hasTrainerCert = false; if (trainer.certifications && trainer.certifications.length > 0) { // Check if any certification is a trainer certification hasTrainerCert = trainer.certifications.some(cert => cert.type.toLowerCase().includes('trainer') || cert.type === 'measureQuick Certified Trainer' ); } else if (trainer.certification_type === 'Certified measureQuick Trainer' || trainer.certification_type === 'measureQuick Certified Trainer') { // Fallback for legacy single certification hasTrainerCert = true; } if (hasTrainerCert) { imageHtml += '
measureQuick Certified Trainer
'; } $imgContainer.html(imageHtml); // Update profile info $trainerModal.find('.hvac-modal-location').text(`${trainer.city}, ${trainer.state}`); // Update certifications section - handle both single and multiple certifications const $certContainer = $trainerModal.find('.hvac-modal-certification-badges'); let certHtml = ''; if (trainer.certifications && trainer.certifications.length > 0) { // Show multiple certifications as badges trainer.certifications.forEach(function(cert) { const badgeClass = cert.type.toLowerCase() .replace('measurequick certified ', '') .replace(/\s+/g, '-'); const legacyClass = cert.status === 'legacy' ? ' hvac-cert-legacy' : ''; certHtml += `${cert.type}`; }); } else if (trainer.certification_type && trainer.certification_type !== 'HVAC Trainer') { // Fallback to legacy single certification const badgeClass = trainer.certification_type.toLowerCase() .replace('measurequick certified ', '') .replace(/\s+/g, '-'); certHtml = `${trainer.certification_type}`; } else { // Default fallback certHtml = 'HVAC Trainer'; } $certContainer.html(certHtml); $trainerModal.find('.hvac-modal-business').text(trainer.business_type || ''); $trainerModal.find('.hvac-modal-events span').text(trainer.event_count || 0); // Update training details $trainerModal.find('.hvac-training-formats').text(trainer.training_formats || 'Various'); $trainerModal.find('.hvac-training-locations').text(trainer.training_locations || 'On-site'); // Show loading state for events $trainerModal.find('.hvac-events-list').html('
  • Loading upcoming events...
  • '); // Set hidden fields for contact form $contactForm.find('input[name="trainer_id"]').val(trainer.user_id || ''); $contactForm.find('input[name="trainer_profile_id"]').val(trainer.profile_id); // Reset contact form $contactForm[0].reset(); $('.hvac-form-message').hide(); // Show modal $trainerModal.fadeIn(300); // Fetch upcoming events via AJAX fetchUpcomingEvents(trainer.profile_id); } /** * Fetch upcoming events for a trainer via AJAX */ function fetchUpcomingEvents(profileId) { if (!profileId) { $trainerModal.find('.hvac-events-list').html('
  • No upcoming events scheduled
  • '); return; } $.post(hvac_find_trainer.ajax_url, { action: 'hvac_get_trainer_upcoming_events', nonce: hvac_find_trainer.nonce, profile_id: profileId }, function(response) { if (response.success && response.data.events) { let eventsHtml = ''; if (response.data.events.length > 0) { response.data.events.forEach(function(event) { eventsHtml += `
  • ${event.title} - ${event.date}
  • `; }); } else { eventsHtml = '
  • No upcoming events scheduled
  • '; } $trainerModal.find('.hvac-events-list').html(eventsHtml); } else { $trainerModal.find('.hvac-events-list').html('
  • No upcoming events scheduled
  • '); } }).fail(function() { $trainerModal.find('.hvac-events-list').html('
  • Unable to load events
  • '); }); } /** * Handle contact form submission */ function handleContactSubmit(e) { e.preventDefault(); const $form = $(this); const $submitBtn = $form.find('.hvac-form-submit'); const $successMsg = $form.find('.hvac-form-success'); const $errorMsg = $form.find('.hvac-form-error'); const originalText = $submitBtn.text(); $submitBtn.text('Sending...').prop('disabled', true); // For now, just show success message setTimeout(function() { $successMsg.show(); $errorMsg.hide(); $form[0].reset(); $submitBtn.text(originalText).prop('disabled', false); // Hide success message after 5 seconds setTimeout(function() { $successMsg.fadeOut(); }, 5000); }, 1000); } /** * Handle search input */ function handleSearch() { const searchTerm = $('.hvac-search-input').val(); if (isLoading) return; updateClearButtonVisibility(); currentPage = 1; loadFilteredTrainers(); } /** * Handle pagination */ function handlePagination(e) { e.preventDefault(); currentPage = $(this).data('page'); loadFilteredTrainers(); // Scroll to top of trainer grid $('html, body').animate({ scrollTop: $('.hvac-trainer-directory-container').offset().top - 100 }, 500); } /** * Load filtered trainers via AJAX */ function loadFilteredTrainers() { if (isLoading) return; isLoading = true; const $container = $('.hvac-trainer-grid'); let $pagination = $('.hvac-pagination'); // Show loading state $container.addClass('hvac-loading'); // Prepare data const data = { action: 'hvac_filter_trainers', nonce: hvac_find_trainer.nonce, page: currentPage, search: $('.hvac-search-input').val(), // Flatten the activeFilters for PHP processing ...activeFilters }; // Make AJAX request $.post(hvac_find_trainer.ajax_url, data, function(response) { if (response.success) { // Our PHP returns an array of trainer card HTML if (response.data.trainers && response.data.trainers.length > 0) { const trainersHtml = response.data.trainers.join(''); $container.html(trainersHtml); } else { $container.html('

    No trainers found matching your criteria. Please try adjusting your filters.

    '); } // Update count display if exists if (response.data.count !== undefined) { $('.hvac-trainer-count').text(response.data.count + ' trainers found'); } // Simple pagination logic - show/hide existing pagination based on results if (response.data.count > 12) { // Assuming 12 per page if ($pagination.length > 0) { $pagination.show(); } } else { if ($pagination.length > 0) { $pagination.hide(); } } } else { console.error('Failed to load trainers:', response); $container.html('

    Error loading trainers. Please try again.

    '); } }).fail(function(xhr) { console.error('AJAX error:', xhr); }).always(function() { isLoading = false; $container.removeClass('hvac-loading'); }); } /** * Close all modals */ function closeModals() { // Remove the modal-active class and force hide styles $filterModal.removeClass('modal-active'); // Force hide styles with !important $filterModal[0].style.setProperty('display', 'none', 'important'); $filterModal[0].style.setProperty('visibility', 'hidden', 'important'); $filterModal[0].style.setProperty('opacity', '0', 'important'); $trainerModal.fadeOut(300); } /** * Debounce helper function */ function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } /** * Clear all filters */ function clearAllFilters() { activeFilters = {}; $('.hvac-search-input').val(''); updateActiveFiltersDisplay(); updateClearButtonVisibility(); currentPage = 1; loadFilteredTrainers(); } /** * Update clear button visibility */ function updateClearButtonVisibility() { const hasFilters = Object.keys(activeFilters).length > 0; const hasSearch = $('.hvac-search-input').val().trim() !== ''; if (hasFilters || hasSearch) { $('.hvac-clear-filters').show(); } else { $('.hvac-clear-filters').hide(); } } /** * Handle direct profile URL access * When someone accesses /find-a-trainer/profile/{id}, show the profile and handle interactions */ function handleDirectProfileAccess() { // Check if we're showing a direct profile if (hvac_find_trainer.show_direct_profile && hvac_find_trainer.direct_profile_id) { console.log('Direct profile access detected for profile ID:', hvac_find_trainer.direct_profile_id); // Update page title in browser if (document.title.includes('Find a Trainer')) { document.title = document.title.replace('Find a Trainer', 'Trainer Profile'); } // Bind contact trainer button $(document).on('click', '.hvac-contact-trainer-btn', function(e) { e.preventDefault(); const profileId = $(this).data('profile-id'); showTrainerModal(profileId); }); // Update URL without page reload for clean sharing const currentUrl = window.location.href; if (currentUrl.includes('/profile/') && window.history && window.history.replaceState) { const cleanUrl = currentUrl.split('?')[0]; // Remove any query parameters window.history.replaceState({}, document.title, cleanUrl); } } } // Expose showTrainerModal globally for MapGeo integration window.showTrainerModal = showTrainerModal; })(jQuery);