1jQuery( function( $ ) { 2 // Helper function to get translation strings 3 function get_translation_string( string_type ) { 4 switch( string_type ) { 5 case 'required': 6 return 'This field is required.'; 7 case 'invalid_email': 8 return 'Please enter a valid email address.'; 9 case 'invalid_phone': 10 return 'Please enter a valid phone number.'; 11 default: 12 return ''; 13 } 14 } 15 16 // Email validation function 17 function is_valid_email( email ) { 18 var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 19 return emailRegex.test( email ); 20 } 21 22 // Phone validation function (basic international format) 23 function is_valid_phone( phone ) { 24 var phoneRegex = /^[\+]?[0-9\s\-\(\)]{10,}$/; 25 return phoneRegex.test( phone.replace(/\s/g, '') ); 26 } 27 28 // check personal information on the checkout page 29 $( document ).on( 'click', '#ep_guest_booking_checkout_button', function() { 30 let ep_gb_error = 0; 31 $( '.ep-error-message' ).html( '' ); 32 let requireString = get_translation_string( 'required' ); 33 let invalidEmailString = get_translation_string( 'invalid_email' ); 34 let invalidPhoneString = get_translation_string( 'invalid_phone' ); 35 36 // First Name (always required) 37 let ep_booking_guest_booking_field_ep_gb_first_name = $( '#ep_booking_guest_booking_field_ep_gb_first_name' ).val(); 38 if( !ep_booking_guest_booking_field_ep_gb_first_name || ep_booking_guest_booking_field_ep_gb_first_name.trim() === '' ) { 39 $( '#ep_booking_guest_booking_field_ep_gb_first_name_error' ).html( requireString ); 40 ep_gb_error = 1; 41 } 42 43 // Email (always required) 44 let ep_booking_guest_booking_field_ep_gb_email = $( '#ep_booking_guest_booking_field_ep_gb_email' ).val(); 45 if( !ep_booking_guest_booking_field_ep_gb_email || ep_booking_guest_booking_field_ep_gb_email.trim() === '' ) { 46 $( '#ep_booking_guest_booking_field_ep_gb_email_error' ).html( requireString ); 47 ep_gb_error = 1; 48 } else { 49 if( !is_valid_email( ep_booking_guest_booking_field_ep_gb_email ) ) { 50 $( '#ep_booking_guest_booking_field_ep_gb_email_error' ).html( invalidEmailString ); 51 ep_gb_error = 1; 52 } 53 } 54 55 // Phone (required if field is present and marked required) 56 if( $( '#ep_booking_guest_booking_field_ep_gb_phone' ).length > 0 ) { 57 let ep_booking_guest_booking_field_ep_gb_phone = $( '#ep_booking_guest_booking_field_ep_gb_phone' ).val(); 58 if( $( '#ep_booking_guest_booking_field_ep_gb_phone' ).prop( 'required' ) ) { 59 if( !ep_booking_guest_booking_field_ep_gb_phone || ep_booking_guest_booking_field_ep_gb_phone.trim() === '' ) { 60 $( '#ep_booking_guest_booking_field_ep_gb_phone_error' ).html( requireString ); 61 ep_gb_error = 1; 62 } else { 63 if( !is_valid_phone( ep_booking_guest_booking_field_ep_gb_phone ) ) { 64 $( '#ep_booking_guest_booking_field_ep_gb_phone_error' ).html( invalidPhoneString ); 65 ep_gb_error = 1; 66 } 67 } 68 } else if( ep_booking_guest_booking_field_ep_gb_phone && ep_booking_guest_booking_field_ep_gb_phone.trim() !== '' ) { 69 // If not required but filled, still validate phone format 70 if( !is_valid_phone( ep_booking_guest_booking_field_ep_gb_phone ) ) { 71 $( '#ep_booking_guest_booking_field_ep_gb_phone_error' ).html( invalidPhoneString ); 72 ep_gb_error = 1; 73 } 74 } 75 } 76 77 // Validate checkout fields 78 let $checkoutSection = $( '.ep-guest-booking-form-checkout-fields-section' ); 79 80 // 1. Basic input fields (text, email, tel, date, number, etc.) 81 let basicInputFields = $checkoutSection.find( 'input[type="text"], input[type="email"], input[type="tel"], input[type="date"], input[type="number"], input[type="password"], input[type="url"]' ); 82 $.each( basicInputFields, function() { 83 let $field = $( this ); 84 if( $field.prop( 'required' ) ) { 85 let field_val = $field.val(); 86 if( !field_val || field_val.trim() === '' ) { 87 let $errorDiv = $field.next( '.ep-error-message' ); 88 if( $errorDiv.length === 0 ) { 89 $errorDiv = $field.closest( '.ep-mb-3' ).find( '.ep-error-message' ); 90 } 91 $errorDiv.html( requireString ); 92 ep_gb_error = 1; 93 } 94 } 95 }); 96 97 // 2. Textarea fields 98 let textareaFields = $checkoutSection.find( 'textarea' ); 99 $.each( textareaFields, function() { 100 let $textarea = $( this ); 101 if( $textarea.prop( 'required' ) ) { 102 if( !$textarea.val() || $textarea.val().trim() === '' ) { 103 let $errorDiv = $textarea.next( '.ep-error-message' ); 104 if( $errorDiv.length === 0 ) { 105 $errorDiv = $textarea.closest( '.ep-mb-3' ).find( '.ep-error-message' ); 106 } 107 $errorDiv.html( requireString ); 108 ep_gb_error = 1; 109 } 110 } 111 }); 112 113 // 3. Select/dropdown fields 114 let selectFields = $checkoutSection.find( 'select' ); 115 $.each( selectFields, function() { 116 let $select = $( this ); 117 if( $select.prop( 'required' ) ) { 118 if( !$select.val() || $select.val() === '' ) { 119 let $errorDiv = $select.next( '.ep-error-message' ); 120 if( $errorDiv.length === 0 ) { 121 $errorDiv = $select.closest( '.ep-mb-3' ).find( '.ep-error-message' ); 122 } 123 $errorDiv.html( requireString ); 124 ep_gb_error = 1; 125 } 126 } 127 }); 128 129 // 4. Radio buttons validation 130 let radioGroups = {}; 131 let radioFields = $checkoutSection.find( 'input[type="radio"]' ); 132 $.each( radioFields, function() { 133 let $radio = $( this ); 134 let name = $radio.attr( 'name' ); 135 136 if( !radioGroups[name] && $radio.prop( 'required' ) ) { 137 radioGroups[name] = true; 138 139 // Check if any radio in this group is selected 140 let $radioGroup = $checkoutSection.find( 'input[name="' + name + '"]' ); 141 let isChecked = false;
142 $.each( $radioGroup, function() { 143 if( $( this ).is( ':checked' ) ) { 144 isChecked = true; 145 } 146 }); 147 148 if( !isChecked ) { 149 let $container = $radioGroup.first().closest( '.ep-form-check-group, .ep-mb-3' ); 150 let $errorDiv = $container.find( '.ep-error-message' ); 151 if( $errorDiv.length === 0 ) { 152 $errorDiv = $container.next( '.ep-error-message' ); 153 } 154 $errorDiv.html( requireString ); 155 ep_gb_error = 1; 156 } 157 } 158 }); 159 160 // 5. Checkbox validation 161 // 5. Checkbox validation - FIXED VERSION 162let checkboxGroups = {}; 163let checkboxFields = $checkoutSection.find( 'input[type="checkbox"]' ); 164 165$.each( checkboxFields, function() { 166 let $checkbox = $( this ); 167 let name = $checkbox.attr( 'name' ); 168 169 // Handle single checkboxes (not in groups) 170 if( !name.includes('[]') && $checkbox.prop( 'required' ) ) { 171 if( !$checkbox.is( ':checked' ) ) { 172 let $container = $checkbox.closest( '.ep-form-check, .ep-mb-3' ); 173 let $errorDiv = $container.find( '.ep-error-message' ); 174 if( $errorDiv.length === 0 ) { 175 $errorDiv = $container.next( '.ep-error-message' ); 176 } 177 $errorDiv.html( requireString ); 178 ep_gb_error = 1; 179 } 180 } 181 // Handle checkbox groups (with [] in name) 182 else if( name.includes('[]') && $checkbox.prop( 'required' ) ) { 183 let baseName = name.replace('[]', ''); 184 185 if( !checkboxGroups[baseName] ) { 186 checkboxGroups[baseName] = true; 187 188 // Check if any checkbox in this group is selected 189 let $checkboxGroup = $checkoutSection.find( 'input[name="' + name + '"]' ); 190 let isChecked = false; 191 192 $.each( $checkboxGroup, function() { 193 if( $( this ).is( ':checked' ) ) { 194 isChecked = true; 195 } 196 }); 197 198 if( !isChecked ) { 199 let $container = $checkboxGroup.first().closest( '.ep-form-check-group, .ep-mb-3' ); 200 let $errorDiv = $container.find( '.ep-error-message' ); 201 if( $errorDiv.length === 0 ) { 202 $errorDiv = $container.next( '.ep-error-message' ); 203 } 204 $errorDiv.html( requireString ); 205 ep_gb_error = 1; 206 } 207 } 208 } 209}); 210 if( ep_gb_error == 1 ) { 211 return false; 212 } else { 213 let event_id = $( 'input[name="ep_event_booking_event_id"]' ).val(); 214 let user_email = $( '#ep_booking_guest_booking_field_ep_gb_email' ).val(); 215 let ticket_data = $( 'input[name="ep_event_booking_ticket_data"]' ).val(); 216 $( '.ep-event-loader' ).show(); 217 218 let data = { 219 action : 'ep_check_event_restrictions', 220 security: eventprime_gb.gb_nonce, 221 event_id: event_id, 222 ticket_data: ticket_data, 223 user_email: user_email 224 }; 225 226 $.ajax({ 227 type : "POST", 228 url : eventprime_gb.ajaxurl, 229 data : data, 230 success : function( response ) { 231 if( response.success == true ) { 232 // SUCCESS: Proceed with booking 233 sessionStorage.setItem( "allow_process_for_payment_step", 1 ); 234 $( '#ep_gb_booking_info_section' ).hide(); 235 $( '#ep_guest_booking_checkout_button' ).hide(); 236 $( '#ep_event_booking_checkout_btn' ).trigger( 'click' ); 237 238 if( $( '#ep-woocommerce-checkout-forms' ).length > 0 ) { 239 sessionStorage.setItem( "allow_process_for_payment_step", 0 ); 240 $( '#ep-woocommerce-checkout-forms' ).show( 500 ); 241 $( '#ep_woocommerce_integration_checkout_button' ).show( 500 ); 242 } 243 244 $( '.ep-event-loader' ).hide(); 245 return true; 246 } else { 247 // ERROR: Show restriction message but DON'T remove the checkout button 248 $( '#ep_guest_booking_checkout_error' ).html( response.data.message ); 249 $( '.ep-event-loader' ).hide(); 250 251 // Scroll to error message 252 $( 'html, body' ).animate({ 253 scrollTop: $( '#ep_guest_booking_checkout_error' ).offset().top - 100 254 }, 500 ); 255 256 return false;
257 } 258 }, 259 error: function( xhr, status, error ) { 260 console.error( 'AJAX Error:', error ); 261 $( '.ep-event-loader' ).hide(); 262 263 // On AJAX error, proceed with booking anyway (fail-safe) 264 sessionStorage.setItem( "allow_process_for_payment_step", 1 ); 265 $( '#ep_gb_booking_info_section' ).hide(); 266 $( '#ep_guest_booking_checkout_button' ).hide(); 267 $( '#ep_event_booking_checkout_btn' ).trigger( 'click' ); 268 269 if( $( '#ep-woocommerce-checkout-forms' ).length > 0 ) { 270 sessionStorage.setItem( "allow_process_for_payment_step", 0 ); 271 $( '#ep-woocommerce-checkout-forms' ).show( 500 ); 272 $( '#ep_woocommerce_integration_checkout_button' ).show( 500 ); 273 } 274 275 return true; 276 } 277 }); 278 } 279 }); 280});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.