jQuery(document).ready(function($) { const $countrySelect = $('#user_country'); const $stateSelect = $('#user_state'); const $stateOtherInput = $('#user_state_other'); const $registrationForm = $('#hvac-registration-form'); // Headquarters fields const $hqCountrySelect = $('#org_headquarters_country'); const $hqStateSelect = $('#org_headquarters_state'); const $hqStateOtherInput = $('#org_headquarters_state_other'); // Venue fields const $createVenue = $('input[name="create_venue"]'); const $venueDetails = $('#venue-details'); const $venueName = $('#venue_name'); const $businessName = $('#business_name'); const $userCity = $('#user_city'); const $venuePhone = $('#venue_phone'); const $venueWebsite = $('#venue_website'); const $businessPhone = $('#business_phone'); const $businessWebsite = $('#business_website'); // Form validation helpers function showFieldError(fieldId, message) { const $field = $('#' + fieldId); const $existingError = $field.siblings('.error-message'); if ($existingError.length) { $existingError.text(message); } else { $field.after('

' + message + '

'); } $field.addClass('error'); } function clearFieldError(fieldId) { const $field = $('#' + fieldId); $field.siblings('.error-message').remove(); // Use jQuery compatibility fix if (typeof window.HVACjQuery !== 'undefined') { window.HVACjQuery.safeRemoveClass($field, 'error'); } else { try { $field.removeClass('error'); } catch (error) { // Fallback to vanilla JavaScript if ($field[0] && $field[0].classList) { $field[0].classList.remove('error'); } } } } // Real-time email validation $('#user_email').on('blur', function() { const email = $(this).val(); if (email && !isValidEmail(email)) { showFieldError('user_email', 'Please enter a valid email address.'); } else { clearFieldError('user_email'); } }); $('#business_email').on('blur', function() { const email = $(this).val(); if (email && !isValidEmail(email)) { showFieldError('business_email', 'Please enter a valid business email address.'); } else { clearFieldError('business_email'); } }); function isValidEmail(email) { const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return re.test(email); } // Real-time password validation $('#user_pass').on('input blur', function() { const password = $(this).val(); if (password) { const errors = []; if (password.length < 8) { errors.push('at least 8 characters'); } if (!/[A-Z]/.test(password)) { errors.push('one uppercase letter'); } if (!/[a-z]/.test(password)) { errors.push('one lowercase letter'); } if (!/[0-9]/.test(password)) { errors.push('one number'); } if (errors.length > 0) { showFieldError('user_pass', 'Password must contain ' + errors.join(', ') + '.'); } else { clearFieldError('user_pass'); // Check confirm password if it has a value const confirmPass = $('#confirm_password').val(); if (confirmPass) { $('#confirm_password').trigger('blur'); } } } }); // Confirm password validation $('#confirm_password').on('blur', function() { const password = $('#user_pass').val(); const confirmPassword = $(this).val(); if (confirmPassword && password !== confirmPassword) { showFieldError('confirm_password', 'Passwords do not match.'); } else { clearFieldError('confirm_password'); } }); // URL validation for optional fields function isValidURL(url) { try { new URL(url); return true; } catch (_) { return false; } } $('#user_url, #user_linkedin, #business_website, #venue_website').on('blur', function() { const url = $(this).val(); const fieldId = $(this).attr('id'); if (url && !isValidURL(url)) { const fieldName = fieldId === 'user_url' ? 'personal website' : fieldId === 'user_linkedin' ? 'LinkedIn profile' : fieldId === 'business_website' ? 'organization website' : 'venue website'; showFieldError(fieldId, 'Please enter a valid URL for your ' + fieldName + '.'); } else { clearFieldError(fieldId); } }); // Handle venue creation toggle $createVenue.on('change', function() { if ($(this).val() === 'Yes') { $venueDetails.slideDown(); // Auto-populate venue name if empty updateVenueName(); // Auto-populate venue phone and website if (!$venuePhone.val() && $businessPhone.val()) { $venuePhone.val($businessPhone.val()); } if (!$venueWebsite.val() && $businessWebsite.val()) { $venueWebsite.val($businessWebsite.val()); } } else { $venueDetails.slideUp(); } }); // Auto-populate venue name function updateVenueName() { if (!$venueName.val()) { const businessName = $businessName.val(); const city = $userCity.val(); if (businessName && city) { $venueName.val(businessName + ' of ' + city); } else if (businessName) { $venueName.val(businessName + ' Training Venue'); } } } // Update venue name when business name or city changes $businessName.on('blur', updateVenueName); $userCity.on('blur', updateVenueName); // Copy organization info to venue fields $businessPhone.on('blur', function() { if (!$venuePhone.val() && $(this).val()) { $venuePhone.val($(this).val()); } }); $businessWebsite.on('blur', function() { if (!$venueWebsite.val() && $(this).val()) { $venueWebsite.val($(this).val()); } }); // Form submission validation $registrationForm.on('submit', function(e) { let hasErrors = false; const errors = []; // Check required fields const requiredFields = [ { id: 'user_email', name: 'Email' }, { id: 'user_pass', name: 'Password' }, { id: 'confirm_password', name: 'Confirm Password' }, { id: 'first_name', name: 'First Name' }, { id: 'last_name', name: 'Last Name' }, { id: 'display_name', name: 'Display Name' }, { id: 'description', name: 'Biographical Info' }, { id: 'business_name', name: 'Organization Name' }, { id: 'business_phone', name: 'Organization Phone' }, { id: 'business_email', name: 'Organization Email' }, { id: 'business_description', name: 'Organization Description' }, { id: 'application_details', name: 'Application Details' } ]; // Check venue fields if creating venue if ($('input[name="create_venue"]:checked').val() === 'Yes') { requiredFields.push( { id: 'venue_name', name: 'Venue Name' }, { id: 'venue_address', name: 'Street Address' }, { id: 'user_country', name: 'Country' }, { id: 'user_city', name: 'City' }, { id: 'user_zip', name: 'Zip/Postal Code' } ); } requiredFields.forEach(field => { const $field = $('#' + field.id); if (!$field.val() || $field.val().trim() === '') { hasErrors = true; errors.push(field.name + ' is required.'); showFieldError(field.id, field.name + ' is required.'); } }); // Check org logo const $orgLogo = $('#org_logo'); if ($orgLogo.length && !$orgLogo[0].files.length) { hasErrors = true; errors.push('Organization Logo is required.'); showFieldError('org_logo', 'Organization Logo is required.'); } // Check state/province for venue if ($('input[name="create_venue"]:checked').val() === 'Yes') { const country = $('#user_country').val(); if (country) { if (country === 'United States' || country === 'Canada') { const state = $('#user_state').val(); if (!state || state === '') { hasErrors = true; errors.push('State/Province is required.'); showFieldError('user_state', 'State/Province is required.'); } } else { const otherState = $('#user_state_other').val(); if (!otherState || otherState.trim() === '') { hasErrors = true; errors.push('State/Province is required.'); showFieldError('user_state_other', 'State/Province is required.'); } } } } // Check radio buttons if (!$('input[name="create_venue"]:checked').length) { hasErrors = true; errors.push('Please select whether to create a training venue profile.'); } // Check business type dropdown const businessType = $('#business_type').val(); if (!businessType || businessType === '') { hasErrors = true; errors.push('Business Type is required.'); showFieldError('business_type', 'Business Type is required.'); } // Check checkbox groups const checkboxGroups = [ { name: 'training_audience[]', label: 'Training Audience' }, { name: 'training_formats[]', label: 'Training Formats' }, { name: 'training_locations[]', label: 'Training Locations' }, { name: 'training_resources[]', label: 'Training Resources' } ]; checkboxGroups.forEach(group => { if (!$('input[name="' + group.name + '"]:checked').length) { hasErrors = true; errors.push('Please select at least one option for ' + group.label + '.'); } }); if (hasErrors) { e.preventDefault(); // Show error summary at the top let $errorSummary = $('.hvac-form-errors'); if (!$errorSummary.length) { $errorSummary = $(''); $registrationForm.prepend($errorSummary); } const $errorList = $errorSummary.find('ul'); $errorList.empty(); errors.forEach(error => { $errorList.append('
  • ' + error + '
  • '); }); // Scroll to top of form $('html, body').animate({ scrollTop: $('.hvac-registration-form').offset().top - 100 }, 500); } }); // Function to populate states/provinces function loadStates(country) { console.log(`Loading states/provinces for ${country}`); // Keep log for debugging $stateSelect.find('option').not('[value=""],[value="Other"]').remove(); // Clear existing options except defaults let options = {}; if (country === 'United States' && typeof hvacRegistrationData !== 'undefined' && hvacRegistrationData.states) { options = hvacRegistrationData.states; } else if (country === 'Canada' && typeof hvacRegistrationData !== 'undefined' && hvacRegistrationData.provinces) { options = hvacRegistrationData.provinces; } else { // If country is not US/CA or data is missing, ensure 'Other' is selected and input shown $stateSelect.val('Other').trigger('change'); // Trigger change to show 'Other' input if needed return; } // Append new options $.each(options, function(value, label) { // Append before the 'Other' option if it exists, otherwise just append const $otherOption = $stateSelect.find('option[value="Other"]'); const $newOption = $('').val(value).text(label); if ($otherOption.length > 0) { $newOption.insertBefore($otherOption); } else { $stateSelect.append($newOption); } }); // Ensure the 'Other' input is hidden initially when states/provinces are loaded $stateOtherInput.hide().val(''); // Reset state selection to default prompt $stateSelect.val(''); } // Handle state/province field visibility based on 'Other' selection $stateSelect.change(function() { if ($(this).val() === 'Other') { $stateOtherInput.show().prop('required', true); // Make required if Other is selected } else { $stateOtherInput.hide().val('').prop('required', false); // Hide and make not required } }).trigger('change'); // Trigger on load to set initial visibility // Handle country change to show/hide/populate state field $countrySelect.change(function() { const country = $(this).val(); if (country === 'United States' || country === 'Canada') { loadStates(country); $stateSelect.show().prop('required', true); // Show and require state select $stateOtherInput.prop('required', false); // Ensure 'Other' input is not required initially } else if (country) { // For other countries, hide state select, select 'Other', show/require 'Other' input $stateSelect.hide().val('Other').prop('required', false); // Hide and make not required $stateOtherInput.show().prop('required', true); // Show and require 'Other' input } else { // No country selected $stateSelect.hide().val('').prop('required', false); // Hide and make not required $stateOtherInput.hide().val('').prop('required', false); // Hide and make not required } }).trigger('change'); // Trigger on load to set initial state based on pre-selected country (if any) // Function to populate headquarters states/provinces function loadHqStates(country) { console.log(`Loading HQ states/provinces for ${country}`); $hqStateSelect.find('option').not('[value=""],[value="Other"]').remove(); let options = {}; if (country === 'United States' && typeof hvacRegistrationData !== 'undefined' && hvacRegistrationData.states) { options = hvacRegistrationData.states; } else if (country === 'Canada' && typeof hvacRegistrationData !== 'undefined' && hvacRegistrationData.provinces) { options = hvacRegistrationData.provinces; } else { // For other countries, just select 'Other' without triggering $hqStateSelect.val('Other'); $hqStateOtherInput.show().prop('required', false); return; } // Append new options $.each(options, function(value, label) { const $otherOption = $hqStateSelect.find('option[value="Other"]'); const $newOption = $('').val(value).text(label); if ($otherOption.length > 0) { $newOption.insertBefore($otherOption); } else { $hqStateSelect.append($newOption); } }); // Hide the 'Other' input and reset state selection $hqStateOtherInput.hide().val(''); $hqStateSelect.val(''); } // Handle headquarters state/province field visibility based on 'Other' selection $hqStateSelect.change(function() { if ($(this).val() === 'Other') { $hqStateOtherInput.show().prop('required', false); } else { $hqStateOtherInput.hide().val('').prop('required', false); } }).trigger('change'); // Handle headquarters country change to show/hide/populate state field $hqCountrySelect.change(function() { const country = $(this).val(); if (country === 'United States' || country === 'Canada') { loadHqStates(country); $hqStateSelect.show().prop('required', false); $hqStateOtherInput.prop('required', false); } else if (country) { // For other countries, hide state select, select 'Other', show 'Other' input $hqStateSelect.hide().val('Other').prop('required', false); $hqStateOtherInput.show().prop('required', false); } else { // No country selected $hqStateSelect.hide().val('').prop('required', false); $hqStateOtherInput.hide().val('').prop('required', false); } }).trigger('change'); // Initialize venue visibility on load $createVenue.filter(':checked').trigger('change'); });