1(function( $ ) { 2 'use strict'; 3 4 /** 5 * All of the code for your public-facing JavaScript source 6 * should reside in this file. 7 * 8 * Note: It has been assumed you will write jQuery code here, so the 9 * $ function reference has been prepared for usage within the scope 10 * of this function. 11 * 12 * This enables you to define handlers, for when the DOM is ready: 13 * 14 * $(function() { 15 * 16 * }); 17 * 18 * When the window is loaded: 19 * 20 * $( window ).load(function() { 21 * 22 * }); 23 * 24 * ...and/or other possibilities. 25 * 26 * Ideally, it is not considered best practise to attach more than a 27 * single DOM-ready or window-load handler for a particular page. 28 * Although scripts in the WordPress core, Plugins and Themes may be 29 * practising this, we should strive to set a better example in our own work. 30 */ 31 32 33 $('#gridContainerFrontend .seat.selectable').each(function() { 34 var color = $(this).attr('data-available-color'); 35 $(this).children('div').children('svg').css('fill',color); 36 }); 37 38 // Initialize Select2 with template for custom color indicators 39 $('#ep_ls_front_ticket_choose_ticket').select2({ 40 templateResult: formatOption, 41 templateSelection: formatOption 42 }); 43 44 // show/hide the seat info 45 $( document ).on( 'click', '.ep-als-expand-seat-info', function() { 46 let seat_ticket_id = $( this ).data( 'ticket_id' ); 47 let expand_html = $( this ).html(); 48 if( expand_html == 'expand_less' ) { 49 $( this ).html( 'expand_more' ); 50 } else{ 51 $( this ).html( 'expand_less' ); 52 } 53 $( '#ep_single_ticket'+seat_ticket_id+'_seat_info' ).toggle( 500 ); 54 }); 55 56 57 58 59 //Frontend zoom and zoom out 60 61 62 63 let zoomLevel = 1; 64 const supportsZoom = typeof document.body.style.zoom !== 'undefined'; 65 const $gridContainerFrontend = $('#gridContainerFrontend'); 66 let baseGridHeight = 0; 67 68 $gridContainerFrontend.css('transform-origin', 'top left'); // Fallback for non-zoom browsers 69 70 function updateZoom(isZoomIn = true) { 71 zoomLevel = isZoomIn ? zoomLevel + 0.1 : Math.max(0.1, zoomLevel - 0.1); 72 if (supportsZoom) { 73 if (!baseGridHeight && $gridContainerFrontend.length) { 74 baseGridHeight = $gridContainerFrontend[0].getBoundingClientRect().height; 75 } 76 $gridContainerFrontend.css({ 77 zoom: zoomLevel, 78 transform: '', 79 height: baseGridHeight ? (baseGridHeight / zoomLevel) + 'px' : '' 80 }); 81 } else { 82 $gridContainerFrontend.css('transform', 'scale(' + zoomLevel + ')'); 83 } 84 85 // Class toggles for visual feedback 86 if (isZoomIn) { 87 $gridContainerFrontend.addClass("ep-preview-scale-up").removeClass("ep-preview-scale-down"); 88 } else { 89 $gridContainerFrontend.addClass("ep-preview-scale-down").removeClass("ep-preview-scale-up"); 90 } 91 92 //console.log('Zoom Level:', zoomLevel); 93 } 94 95// Zoom In 96 $('#ep-zoom-plan-in').on('click', function () { 97 updateZoom(true); 98 }); 99 100// Zoom Out 101 $('#ep-zoom-plan-out').on('click', function () { 102 updateZoom(false); 103 }); 104 105 106 107})( jQuery ); 108 109function ep_seat_selection(seat) 110{ 111 jQuery(seat).toggleClass('selected'); 112 var color = jQuery(seat).attr('data-selected-color'); 113 var ticket_id = jQuery(seat).attr('data-ticketid'); 114 var available_color = jQuery(seat).attr('data-available-color'); 115 var virtual_id = jQuery(seat).attr('data-virtual-id'); 116 var seat_id = jQuery(seat).attr('data-ep-als-seat-id'); 117 var amenities = jQuery(seat).attr('data-amenities'); 118 119 //console.log(color); 120 var seatObject = { 121 area_id: ticket_id, 122 uniqueIndex: seat_id, 123 seatSequence: virtual_id, 124 seatColor: available_color, 125 ticket_id: ticket_id, 126 amenities:JSON.parse(amenities) 127}; 128 if(jQuery(seat).hasClass("selected")) 129 { 130 jQuery(seat).children('div').children('svg').css('fill',color); 131 ep_ls_update_cart_tickets_data( 'plus', seatObject ); 132 } 133 else 134 { 135 jQuery(seat).children('div').children('svg').css('fill',available_color); 136 ep_ls_update_cart_tickets_data( 'minus', seatObject ); 137 } 138} 139 140// Function to style each option 141function formatOption(option) { 142 if (!option.id) { 143 return option.text; // Return text for placeholder 144 } 145 146 // Get color from data-style attribute 147 const colorStyle = jQuery(option.element).data('style'); 148 149 // Create a color indicator using a span with the background color 150 return jQuery('<span>').css('background-color', colorStyle.split(':')[1]) 151 .addClass('color-indicator') 152 .css({ 153 'display': 'inline-block', 154 'width': '15px', 155 'height': '15px', 156 'border-radius': '50%', 157 'margin-right': '8px', 158 'vertical-align': 'middle' 159 }) 160 .add(jQuery('<span>').text(option.text)); // Add text after color indicator 161 } 162 163 164function ep_highlight_related_seat(ticket) 165{ 166 var id= jQuery(ticket).val(); 167 168 if(id!=="") 169 { 170 jQuery('.seat').addClass('ep-hide-seat'); 171 jQuery('.ep-hide-seat').removeAttr('onclick'); 172 jQuery('.seat_ticket_'+id).removeClass('ep-hide-seat'); 173 jQuery('.seat_ticket_'+id).attr('onclick','ep_seat_selection(this)'); 174 } 175 else 176 { 177 jQuery('.seat').removeClass('ep-hide-seat'); 178 jQuery('.seat').attr('onclick','ep_seat_selection(this)'); 179 } 180 181} 182 183 184/* seat selection and add to cart */ 185function ep_ls_update_cart_tickets_data(action, column_data) { 186 $= jQuery; 187 if( column_data.ticket_id ) { 188 let ticket_id = column_data.ticket_id; 189 //let ticket_price = column_data.price; 190 let ep_added_ticket_option = $( '#ep_event_booking_ticket' ).attr( 'data-ticket_options' ); 191 let ep_added_offer_option = $('#ep_event_offer_data').val(); 192 193 if( !ep_added_ticket_option ) { 194 ep_added_ticket_option = []; 195 } else{ 196 ep_added_ticket_option = JSON.parse( ep_added_ticket_option ); 197 } 198 199 if( !ep_added_offer_option ) { 200 ep_added_offer_option = []; 201 } else{ 202 ep_added_offer_option = JSON.parse( ep_added_offer_option ); 203 } 204 205 let qty = 0; 206 $.each( ep_added_ticket_option, function( idx, ticket_option ) { 207 if( ticket_option.id == ticket_id ) { 208 ticket_found = 1; 209 added_ticket_option_index = idx; 210 qty = ticket_option.qty; 211 return false;
212 } 213 }); 214 215 if( action == 'plus' ) { 216 qty++; 217 } else{ 218 qty--; 219 } 220 221 if (qty < 0) qty = 0; 222 223 if (qty == 0) { 224 // Remove ticket logic without AJAX request 225 const ticketIndex = ep_added_ticket_option.findIndex( 226 (ticket) => ticket.id === parseInt(ticket_id) 227 ); 228 if (ticketIndex > -1) { 229 ep_added_ticket_option.splice(ticketIndex, 1); // Remove ticket from data 230 } 231 console.log(ticketIndex); 232 // Remove ticket from UI 233 $('#single_ticket_detail' + ticket_id).remove(); 234 // Update ticket options in DOM 235 $('#ep_event_booking_ticket').attr('data-ticket_options', JSON.stringify(ep_added_ticket_option)); 236 // Recalculate total 237 ep_ls_calculate_tickets_total(); 238 239 if( ep_added_ticket_option.length > 0 ) { 240 $( '#ep_als_single_event_checkout_btn' ).removeAttr( 'disabled' ); 241 } else{ 242 $( '#ep_als_single_event_checkout_btn' ).attr( 'disabled', 'disabled' ); 243 } 244 245 return; // Exit the function since no server request is needed 246 } 247 248 // Show loading indicator 249 $('#ep-event-ticket-checkout-modal .ep-loader').show(); 250 $('#ep-event-ticket-checkout-modal .ep-loader').parent('.ep-modal-body').addClass('ep-loader-active'); 251 252 let data = { 253 action: 'ep_als_update_tickets_data', 254 ticket_id: ticket_id, 255 qty: qty, 256 security: em_front_event_object.em_event_data.single_event_nonce 257 }; 258 259 $.ajax({ 260 type : "POST", 261 url : eventprime.ajaxurl, 262 data : data, 263 success : function( response ) { 264 if( response.success == true ) { 265 const data = response.data; 266 const single_ticket_detail_id = 'single_ticket_detail' + data.id; 267 if(response.data) { 268 console.log(response.data); 269 let new_seat_data = { 270 'area_id': column_data.area_id, 271 'seat_data': [{ 272 'uid' : column_data.uniqueIndex, 273 'seat': column_data.seatSequence, 274 'amenities':column_data.amenities 275 }] 276 } 277 var ticket_price = response.data.price; 278 var total_offer_discount_val = response.data.offer; 279 var ticket_price_subtotal = response.data.subtotal; 280 let ticket_var_data = { 281 ...response.data, 282 seats: [new_seat_data], 283 }; 284 const ticketIndex = ep_added_ticket_option.findIndex( 285 (ticket) => ticket.id === data.id 286 ); 287 if (ticketIndex > -1) { 288 // Update existing ticket 289 console.log(ticketIndex); 290 let added_seat_data = ep_added_ticket_option[ticketIndex]; 291 292 if( qty == 0 ) { 293 ep_added_ticket_option.splice( ticketIndex, 1 ); 294 $( '#single_ticket_detail' + added_seat_data.id ).remove(); 295 } else{ 296 added_seat_data.qty = qty; 297 added_seat_data.offer = total_offer_discount_val, 298 added_seat_data.subtotal = ticket_price_subtotal; 299 if( action == 'plus' ) { 300 let area_found = 0; 301 $.each( added_seat_data.seats, function(idx, old_seat_data ) { 302 if( old_seat_data.area_id == column_data.area_id ) { 303 area_found = 1; 304 let osd = old_seat_data.seat_data; 305 let new_seat = { 306 'uid' : column_data.uniqueIndex, 307 'seat': column_data.seatSequence, 308 'amenities':column_data.amenities 309 } 310 old_seat_data.seat_data.push( new_seat ); 311 return false;
312 } 313 }); 314 if( area_found == 0 ) { 315 let new_seat_data = { 316 'area_id': column_data.area_id, 317 'seat_data': [{ 318 'uid' : column_data.uniqueIndex, 319 'seat': column_data.seatSequence, 320 'amenities':column_data.amenities 321 }] 322 } 323 added_seat_data.seats.push( new_seat_data ); 324 } 325 } else{ 326 let seat_found = 0; 327 $.each( added_seat_data.seats, function(idx, old_seat_data ) { 328 if( old_seat_data.area_id == column_data.area_id ) { 329 let osd = old_seat_data.seat_data; 330 $.each( osd, function( os_id, os_data ) { 331 if( os_data.uid == column_data.uniqueIndex ) { 332 old_seat_data.seat_data.splice( os_id, 1 ); 333 return false; 334 } 335 }); 336 } 337 }); 338 } 339 340 ep_added_ticket_option[ticketIndex] = added_seat_data; 341 } 342 } else { 343 // Add new ticket 344 ep_added_ticket_option.push(ticket_var_data); 345 } 346 const ticketHTML = generateTicketHTML(data); 347 348 let formated_price = ep_format_price_with_position( ticket_price ); 349 // Append the HTML to the container 350 if( $( '#ep_event_booking_ticket #' + single_ticket_detail_id ).length > 0 ) { 351 $( '#ep_single_ticket'+ ticket_id +'_qty' ).html( qty ); 352 $( '#ep_single_ticket'+ ticket_id +'_price' ).html( formated_price ); 353 // offer applied text 354 $( '#ep_single_ticket'+ticket_id+'_offer_text' ).html( ticket_var_data.offer_text ); 355 // offer amount 356 $( '#ep_single_ticket'+ticket_id+'_offer_value' ).html( `-${ep_format_price_with_position(ticket_var_data.offer)}` ); 357 358 let ticket_price_subtotal = ticket_var_data.subtotal; 359 // add additional fees 360 if( ticket_var_data.additional_fees ) { 361 $( JSON.parse( ticket_var_data.additional_fees ) ).each( function(ind, data ) { 362 let multi_add_fee = data.price * qty; 363 $( '#ep_additional_price_' + ticket_id + '_' + ind ).html( ep_format_price_with_position( multi_add_fee ) ); 364 ticket_price_subtotal = parseFloat( ticket_price_subtotal ) + parseFloat( multi_add_fee ); 365 }); 366 } 367 $( '#ep_single_ticket'+ ticket_id +'_subtotal' ).html( ep_format_price_with_position( ticket_price_subtotal ) ); 368 $( '#ep_single_ticket'+ ticket_id +'_subtotal' ).data( 'row_subtotal', ticket_price_subtotal); 369 } else { 370 $('#ep_event_booking_ticket').append(ticketHTML); 371 } 372 } 373 $('.ep-event-offer-applied_'+ data.id).hide();
374 data.applied_offer_uid.forEach((offeruid, index) => { 375 $('#ep_event_offer_'+ data.id+'_'+ offeruid).show(); 376 }); 377 378 $('#ep_als_single_event_checkout_btn').prop('disabled', false); 379 380 381 } else { 382 if (response && response.data && response.data.message) { 383 $('#ep_single_event_before_checkout_error_msg').html(response.data.message); 384 } else { 385 $('#ep_single_event_before_checkout_error_msg').html('Error updating tickets.'); 386 } 387 } 388 // return 389 $( '#ep_event_booking_ticket' ).attr( 'data-ticket_options', JSON.stringify( ep_added_ticket_option ) ); 390 // update seat data to info 391 // Get seats data for current tic 392 const currentTicData = ep_added_ticket_option.find(obj => obj.id == ticket_id); 393 const currentTicSeatData = currentTicData.seats[0].seat_data; 394 for ( seatObj of currentTicSeatData ) { 395 //let info_html = '<div class="ep-box-col-12 ep-text-end" id="ep_single_ticket'+ticket_id+'_seat_num_'+seatObj.seat+'">'+seatObj.seat+'</div>'; 396 let amenities_html = ''; 397 if (Array.isArray(seatObj.amenities) && seatObj.amenities.length > 0) { 398 amenities_html = '<ul class="ep-seat-amenities" style="margin-top: 4px; font-size: 12px;">'; 399 400 seatObj.amenities.forEach(function(item) { 401 amenities_html += '<li>'; 402 403 if (item.icon) { 404 amenities_html += '<img src="' + item.icon + '" alt="' + item.title + '" title="' + item.title + '" style="width:16px; height:16px; margin-right:4px; vertical-align:middle;" />'; 405 } 406 else 407 { 408 amenities_html += '<img src="' + ep_als_front_ticket_object.amenity_icon + '" alt="' + item.title + '" title="' + item.title + '" style="width:16px; height:16px; margin-right:4px; vertical-align:middle;" />'; 409 410 } 411 if (item.title) { 412 amenities_html += '<span>' + item.title + '</span>'; 413 } 414 amenities_html += '</li>'; 415 }); 416 417 amenities_html += '</ul>'; 418 } 419 420 let info_html = '<div class="ep-box-col-12 ep-text-end" id="ep_single_ticket' + ticket_id + '_seat_num_' + seatObj.seat + '">' + 421 seatObj.seat + 422 amenities_html + 423 '</div>'; 424 425 426 $( '#ep_single_ticket'+ticket_id+'_seat_info' ).append( info_html ); 427 } 428 ep_ls_calculate_tickets_total(); 429 430 $('#ep_single_event_before_checkout_error_msg').html(''); 431 $('#ep-event-ticket-checkout-modal .ep-loader').parent('.ep-modal-body').removeClass('ep-loader-active'); 432 $('#ep-event-ticket-checkout-modal .ep-loader').hide(); 433 434 } 435 }); 436 if( ep_added_ticket_option.length > 0 ) { 437 $( '#ep_als_single_event_checkout_btn' ).removeAttr( 'disabled' ); 438 } else{ 439 $( '#ep_als_single_event_checkout_btn' ).attr( 'disabled', 'disabled' ); 440 } 441 } 442 443 } 444 445 446 function generateTicketHTML_single_Ticket(ticketData) { 447 const $ = jQuery; 448 let additionalFeesHTML = ''; 449 let offerHtml = ''; 450 let seatHTML = ""; 451 $( '#ep_single_ticket'+ ticketData.id +'_qty' ).html( ticketData.qty ); 452 if (ticketData.additional_fee && ticketData.additional_fee.length > 0) { 453 ticketData.additional_fee.forEach((fee, index) => { 454 additionalFeesHTML += ` 455 <div class="ep-box-col-6 ep-text-small">${fee.label}</div> 456 <div class="ep-box-col-6 ep-text-end ep-text-small" id="ep_additional_price_${ticketData.id}_${index}">${ep_format_price_with_position(fee.price)}</div> 457 `; 458 }); 459 } 460 461 if(ticketData.offer && ticketData.offer > 0) 462 { 463 offerHtml += ` 464 <div class="ep-box-col-6 ep-text-small"> 465 <em id="ep_single_ticket${ticketData.id}_offer_text">${ticketData.offer_text}</em> 466 </div> 467 <div class="ep-box-col-6 ep-text-end ep-text-small" id="ep_single_ticket${ticketData.id}_offer_value">- ${ep_format_price_with_position(ticketData.offer)}</div> 468 `; 469 } 470 471 // seats 472 seatHTML += '<div class="ep-box-col-6 ep-text-small">
472<span id="ep_single_ticket'+ticketData.id+'_seats_text">Seats</span></div>'; 473 seatHTML += '<div class="ep-box-col-6 ep-text-end ep-text-small" id="ep_single_ticket'+ticketData.id+'_seat_down">'; 474 seatHTML += '<span class="material-icons-outlined ep-fs-6 ep-align-middle ep-als-expand-seat-info" data-ticket_id="'+ticketData.id+'">expand_more</span>'; 475 seatHTML += '<div class="ep-ls-seat-info" id="ep_single_ticket'+ticketData.id+'_seat_info" style="display:none;"></div>'; 476 seatHTML += '</div>'; 477 478 return ` 479 <div class="ep-box-col-6"> 480 <span id="ep_single_ticket${ticketData.id}_name">${ticketData.name}</span> x 481 <span class="ep-text-muted" id="ep_single_ticket${ticketData.id}_qty">${ticketData.qty}</span> 482 </div> 483 <div class="ep-box-col-6 ep-text-end" id="ep_single_ticket${ticketData.id}_price">${ep_format_price_with_position(ticketData.price)}</div> 484 <!-- Additional Fees Section --> 485 ${additionalFeesHTML} 486 ${offerHtml} 487 ${seatHTML} 488 <div class="ep-box-col-6 ep-fw-bold mt-2">${em_front_event_object.em_event_data.subtotal_text}</div> 489 <div class="ep-box-col-6 ep-text-end ep-fw-bold mt-2 ep-ticket-subtotal-row" id="ep_single_ticket${ticketData.id}_subtotal" data-row_subtotal="${ticketData.subtotal}"> 490 ${ep_format_price_with_position(ticketData.subtotal)} 491 </div> 492 493 `; 494 } 495 496 function generateTicketHTML(ticketData) { 497 const $ = jQuery; 498 const singleTicketDetailId = 'single_ticket_detail' + ticketData.id; 499 const existingRow = $('#ep_event_booking_ticket #' + singleTicketDetailId); 500 501 // If the ticket row already exists, update the existing values 502 if (existingRow.length > 0) { 503 let ticket_data = generateTicketHTML_single_Ticket(ticketData); 504 $(existingRow).html(ticket_data); 505 } else { 506 // Generate new ticket row 507 let ticData = '<div class="ep-box-row ep-text-small ep-my-2 ep-rounded ep-p-2 ep-single-modal-ticket-row" id="' + singleTicketDetailId + '">'; 508 ticData += generateTicketHTML_single_Ticket(ticketData); 509 ticData += '</div>'; 510 511 return ticData; 512 // Append the new ticket row 513 // $('#ep_event_booking_ticket').append(ticData); 514 } 515 } 516 517 // Calculate tickets total 518 function ep_ls_calculate_tickets_total() { 519 const $ = jQuery; 520 let ticket_total = 0; 521 $( '#ep_event_booking_ticket .ep-ticket-subtotal-row' ).each( function() { 522 let row_subtotal = $( this ).data( 'row_subtotal' ); 523 ticket_total = parseFloat( ticket_total ) + parseFloat( row_subtotal ); 524 }); 525 // check for fixed event price 526 if( $( '#ep_event_fixed_price' ).length > 0 ) { 527 let fixed_price = $( '#ep_event_fixed_price' ).data( 'fixed_price' ); 528 if( fixed_price && fixed_price > 0 ) { 529 ticket_total = parseFloat( ticket_total ) + parseFloat( fixed_price ); 530 } 531 } 532 $( '#ep_ticket_price_total' ).html( ep_format_price_with_position( ticket_total ) ); 533 } 534 535 536 537 // go to checkout 538 jQuery( document ).on( 'click', '#ep_als_single_event_checkout_btn', function() { 539 $ = jQuery; 540 $( '#ep_ls_front_ticket_error_message' ).html( '' ); 541 let ep_event_booking_ticket = $( '#ep_event_booking_ticket' ).attr( 'data-ticket_options' ); 542 if( ep_event_booking_ticket ) { 543 let event_ticket_data = $( '#ep_ls_event_ticket_checkout_modal' ).data( 'event_tickets_data' ); 544 if( event_ticket_data ) { 545 let et_datas = []; 546 $.each( event_ticket_data, function( idx, tic ) { 547 et_datas[tic.id] = tic; 548 }); 549 // check for allowed quantity of tickets 550 var ticket_error = 0; 551 $.each( JSON.parse( ep_event_booking_ticket ), function( idx, tic_data ){ 552 let ticid = tic_data.id; 553 let this_ticket_data = et_datas[ticid]; 554 // check for minimum 555 let min_allowed = this_ticket_data.min_ticket_no; 556 if( min_allowed && tic_data.qty < min_allowed ) { 557 ticket_error = 1; 558 let min_er = ep_als_front_ticket_object.min_qty_error + ' ' + this_ticket_data.name + ' ' + ep_als_front_ticket_object.is_text + ' ' + min_allowed; 559 $( '#ep_ls_front_ticket_error_message' ).html( min_er ); 560 return false;
561 } 562 // check for maximum 563 let max_allowed = this_ticket_data.max_ticket_no; 564 if( max_allowed > 0 && tic_data.qty > max_allowed ) { 565 ticket_error = 1; 566 let max_er = ep_als_front_ticket_object.max_qty_error + ' ' + this_ticket_data.name + ' ' + ep_als_front_ticket_object.is_text + ' ' + max_allowed; 567 $( '#ep_ls_front_ticket_error_message' ).html( max_er ); 568 return false; 569 } 570 }); 571 572 if ( ! ticket_error ) { 573 // check if seats are hold 574 let booking_event_id = $( '#ep_event_booking_event_id' ).val(); 575 let data = { 576 action : 'ep_als_check_ticket_for_hold_before_booking', 577 security : ep_als_front_ticket_object.check_seats_for_hold_nonce, 578 ticket_data: ep_event_booking_ticket, 579 do_hold : 1, 580 event_id : booking_event_id 581 }; 582 $.ajax({ 583 type: 'POST', 584 url : eventprime.ajaxurl, 585 data: data, 586 success: function( response, textStatus, XMLHttpRequest ) { 587 if( !response.success ) { 588 ticket_error = 1; 589 if( response.data.hold_seats_data ) { 590 let no_of_hold_seats = response.data.hold_seats_data.length; 591 $( '#ep_ls_front_ticket_error_message' ).html( no_of_hold_seats + ' ' + response.data.message ); 592 } else{ 593 $( '#ep_ls_front_ticket_error_message' ).html( response.data.message ); 594 } 595 return false; 596 } 597 if( ticket_error == 0 ) { 598 let ep_event_offer_data = $( '#ep_event_offer_data' ).val(); 599 let booking_data = { 600 ticket: ep_event_booking_ticket, 601 event: booking_event_id, 602 ep_event_offer_data:ep_event_offer_data, 603 }; 604 // check if rsvp booking data saved in the session 605 let ep_event_rsvp_booking_data = sessionStorage.getItem( 'ep_event_rsvp_booking_data' ); 606 if( ep_event_rsvp_booking_data ) { 607 booking_data.rsvp_booking_data = ep_event_rsvp_booking_data 608 } 609 $( '#ep_event_booking_data' ).val( JSON.stringify( booking_data ) ); 610 $( '#ep_event_booking_form' ).submit(); 611 } 612 } 613 }); 614 } 615 616 // if( ticket_error == 0 ) { 617 // let booking_data = { 618 // ticket: ep_event_booking_ticket, 619 // event: booking_event_id 620 // }; 621 // // check if rsvp booking data saved in the session 622 // let ep_event_rsvp_booking_data = sessionStorage.getItem( 'ep_event_rsvp_booking_data' ); 623 // if( ep_event_rsvp_booking_data ) { 624 // booking_data.rsvp_booking_data = ep_event_rsvp_booking_data 625 // } 626 // $( '#ep_event_booking_data' ).val( JSON.stringify( booking_data ) ); 627 // $( '#ep_event_booking_form' ).submit(); 628 // } 629 } else{ 630 $( '#ep_ls_front_ticket_error_message' ).html( ep_als_front_ticket_object.no_seat_error ); 631 } 632 } else{ 633 $( '#ep_ls_front_ticket_error_message' ).html( ep_als_front_ticket_object.no_seat_error ); 634 } 635 }); 636 637 638 jQuery('#ep_auto_assign_seats').on('click', function () { 639 const $ = jQuery; 640 const count = parseInt($('#ep_random_seat_count').val()); 641 if (!count || count <= 0) { 642 alert('Please enter a valid seat count.'); 643 return; 644 } 645 646 $('#ep_event_booking_ticket').attr('data-ticket_options',''); 647 $('#ep_event_booking_ticket').html(''); 648 649 650 // Reset UI selections 651 $('.ep-selectable.selected').removeClass('selected').each(function () { 652 $(this).children('div').children('svg').css('fill', $(this).attr('data-available-color')); 653 }); 654 655 const availableSeats = $('.ep-selectable') 656 .not('.ep-booked, .ep-reserved, .ep-unselected, .ep-hide-seat, .selected'); 657 658 if (availableSeats.length < count) { 659 alert('Not enough available seats.'); 660 return; 661 } 662 663// const shuffled = availableSeats.sort(() => 0.5 - Math.random()).slice(0, count); 664// 665// const seatGroups = {}; // {ticket_id: [DOM elements]} 666// shuffled.each(function () { 667// const $seat = $(this); 668// const ticketId = $seat.attr('data-ticketid'); 669// if (!seatGroups[ticketId]) { 670// seatGroups[ticketId] = []; 671// } 672// seatGroups[ticketId].push($seat); 673// }); 674// 675// const seatPayload = []; 676//
677// Object.keys(seatGroups).forEach(function (ticketId) { 678// seatPayload.push({ 679// ticket_id: ticketId, 680// qty: seatGroups[ticketId].length 681// }); 682// }); 683 684 685const shuffled = availableSeats.sort(() => 0.5 - Math.random()).slice(0, count); 686 687 const seatGroups = {}; // Grouped by ticket ID 688 689 shuffled.each(function () { 690 const $seat = $(this); 691 const ticketId = $seat.attr('data-ticketid'); 692 693 694 let amenitiesRaw = $seat.attr('data-amenities'); 695 let amenitiesParsed = []; 696 697 try { 698 if (amenitiesRaw && amenitiesRaw !== '[]') { 699 amenitiesParsed = JSON.parse(amenitiesRaw); 700 } 701 } catch (e) { 702 // Log error or ignore 703 amenitiesParsed = []; 704 } 705 706 const seatData = { 707 uid: $seat.attr('data-ep-als-seat-id'), 708 seat: $seat.attr('data-virtual-id'), 709 amenities: amenitiesParsed 710 }; 711 712 713 714// const seatData = { 715// uid: $seat.attr('data-ep-als-seat-id'), 716// seat: $seat.attr('data-virtual-id'), 717// //seatSequence: $seat.attr('data-virtual-id'), 718// amenities: $seat.attr('data-amenities') 719// }; 720 console.log(seatData); 721 if (!seatGroups[ticketId]) { 722 seatGroups[ticketId] = []; 723 } 724 seatGroups[ticketId].push({ 725 dom: $seat, 726 data: seatData 727 }); 728 }); 729 730 const payload = []; // For AJAX 731 const uiData = []; // For updating right side cart 732 733 Object.keys(seatGroups).forEach(ticketId => { 734 payload.push({ 735 ticket_id: ticketId, 736 qty: seatGroups[ticketId].length, 737 seat_data: seatGroups[ticketId].map(s => s.data) 738 739 }); 740 741// uiData.push({ 742// id: ticketId, 743// seats: [{ 744// seat_data: seatGroups[ticketId].map(s => s.data) 745// }] 746// }); 747 748 749 uiData.push({ 750 id: ticketId, 751 price: parseFloat($('#ep_single_ticket' + ticketId + '_price').attr('data-price')) || 0, 752 qty: seatGroups[ticketId].length, 753 total: parseFloat($('#ep_single_ticket' + ticketId + '_price').attr('data-price')) * seatGroups[ticketId].length, 754 seats: [{ 755 seat_data: seatGroups[ticketId].map(s => s.data) 756 }] 757 }); 758 759 760 }); 761console.log("Before sending:", JSON.stringify(payload)); 762 763 // AJAX to new endpoint 764 $.ajax({ 765 type: 'POST', 766 url: eventprime.ajaxurl, 767 data: { 768 action: 'ep_als_bulk_assign_tickets_data', 769 security: em_front_event_object.em_event_data.single_event_nonce, 770 seats: JSON.stringify(payload) 771 }, 772 success: function (response) { 773 // console.log(response); 774 ep_ls_update_bulk_cart_tickets(response.data.results); 775 if (response.success && response.data.results) { 776 // On success, update visual seats 777 Object.keys(seatGroups).forEach(function (ticketId) { 778 seatGroups[ticketId].forEach(function ($seat) { 779 // Locate actual seat element using seat UID 780 //console.log($seat.data); 781 const seatElement = $(`[data-ep-als-seat-id="${$seat.data.uid}"]`); 782 seatElement.addClass('selected'); 783 seatElement.children('div').children('svg').css('fill', seatElement.attr('data-selected-color')); 784 785 //$seat.addClass('selected'); 786 //$seat.children('div').children('svg').css('fill', $seat.attr('data-selected-color')); 787 }); 788 }); 789 } else { 790 alert('Seat assignment failed.'); 791 //console.warn(response); 792 } 793 }, 794 error: function (err) { 795 console.error('Bulk seat AJAX error:', err); 796 } 797 }); 798 }); 799 800 /* 801 jQuery('#ep_auto_assign_seats').on('click', function () { 802 const $ = jQuery; 803 const count = parseInt($('#ep_random_seat_count').val()); 804 if (!count || count <= 0) { 805 alert('Please enter a valid seat count.'); 806 return; 807 } 808 809 // Clear previous selections 810 $('.ep-selectable.selected').removeClass('selected').each(function () { 811 $(this).children('div').children('svg').css('fill', $(this).attr('data-available-color')); 812 }); 813 814 const availableSeats = $('.ep-selectable') 815 .not('.ep-booked, .ep-reserved, .ep-unselected, .ep-hide-seat, .selected'); 816 817 if (availableSeats.length < count) { 818 alert('Not enough available seats.'); 819 return; 820 } 821 822 const shuffled = availableSeats.sort(() => 0.5 - Math.random()).slice(0, count); 823 824 const seatGroups = {}; // Grouped by ticket ID 825 826 shuffled.each(function () { 827 const $seat = $(this); 828 const ticketId = $seat.attr('data-ticketid'); 829 const seatData = { 830 uid: $seat.attr('data-ep-als-seat-id'), 831 seat: $seat.attr('data-virtual-id'), 832 //seatSequence: $seat.attr('data-virtual-id'), 833 amenities: $seat.attr('data-amenities') ? JSON.parse($seat.attr('data-amenities')) : [] 834 }; 835 836 if (!seatGroups[ticketId]) { 837 seatGroups[ticketId] = []; 838 } 839 seatGroups[ticketId].push({ 840 dom: $seat, 841 data: seatData 842 }); 843 }); 844 845 const payload = []; // For AJAX 846 const uiData = []; // For updating right side cart 847
848 Object.keys(seatGroups).forEach(ticketId => { 849 payload.push({ 850 ticket_id: ticketId, 851 qty: seatGroups[ticketId].length 852 }); 853 854// uiData.push({ 855// id: ticketId, 856// seats: [{ 857// seat_data: seatGroups[ticketId].map(s => s.data) 858// }] 859// }); 860 861 862 uiData.push({ 863 id: ticketId, 864 price: parseFloat($('#ep_single_ticket' + ticketId + '_price').attr('data-price')) || 0, 865 qty: seatGroups[ticketId].length, 866 total: parseFloat($('#ep_single_ticket' + ticketId + '_price').attr('data-price')) * seatGroups[ticketId].length, 867 seats: [{ 868 seat_data: seatGroups[ticketId].map(s => s.data) 869 }] 870 }); 871 872 873 }); 874 875 // Send minimal data to backend 876 $.ajax({ 877 type: 'POST', 878 url: eventprime.ajaxurl, 879 data: { 880 action: 'ep_als_bulk_assign_tickets_data', 881 security: em_front_event_object.em_event_data.single_event_nonce, 882 seats: payload 883 }, 884 success: function (response) { 885 if (response.success) { 886 // Add visual + update right side panel with precompiled data 887 Object.keys(seatGroups).forEach(ticketId => { 888 seatGroups[ticketId].forEach(({ dom }) => { 889 dom.addClass('selected'); 890 dom.children('div').children('svg').css('fill', dom.attr('data-selected-color')); 891 }); 892 }); 893 894 // Directly update the cart without waiting for backend to return seat details 895 ep_ls_update_bulk_cart_tickets(uiData); 896 } else { 897 alert('Seat assignment failed.'); 898 console.warn(response); 899 } 900 }, 901 error: function (err) { 902 console.error('Bulk seat AJAX error:', err); 903 } 904 }); 905}); 906*/ 907 908function ep_ls_bulk_assign_seats(seatObjects) { 909 const $ = jQuery; 910 // Step 1: Clone the current ticket_options 911 let ticketOptionsJson = $('#ep_event_booking_ticket').attr('data-ticket_options'); 912 let ticketOptions = ticketOptionsJson ? JSON.parse(ticketOptionsJson) : []; 913 914 seatObjects.forEach((seatObj) => { 915 let ticketId = seatObj.id; 916 let seatData = seatObj.seat_data; 917 918 let ticketIndex = ticketOptions.findIndex(opt => opt.id == ticketId); 919 920 if (ticketIndex === -1) { 921 // If not found, create a new ticket entry 922 ticketOptions.push({ 923 id: ticketId, 924 category_id: '0', 925 name: seatObj.name || '', 926 price: parseFloat(seatObj.price) || 0, 927 qty: seatObj.qty, 928 offer: 0, 929 additional_fee: [], 930 subtotal: parseFloat(seatObj.price) * seatObj.qty || 0, 931 offer_text: "", 932 total_offer_discount_text: 0, 933 formatted_subtotal: parseFloat(seatObj.price) * seatObj.qty || 0, 934 applied_offer_uid: [], 935 applied_offer_obj: [], 936 seats: [ 937 { 938 area_id: seatObj.id, 939 seat_data: [{ 940 uid : seatObj.uid, 941 seat: seatObj.seat, 942 amenities:seatObj.amenities 943 }] 944 945 } 946 ] 947 }); 948 } else { 949 // Merge with existing ticket 950 let existing = ticketOptions[ticketIndex]; 951 let area = existing.seats.find(s => s.area_id == seatObj.area_id); 952 if (!area) { 953 existing.seats.push({ 954 area_id: seatObj.area_id, 955 seat_data: [{ 956 uid : seatObj.uid, 957 seat: seatObj.seat, 958 amenities:seatObj.amenities 959 }] 960 }); 961 } else { 962 area.seat_data.push(...seatData.map(sd => ({ 963 uid: sd.uid, 964 seat: sd.seat, 965 amenities: [] 966 }))); 967 } 968 969 existing.qty += seatData.length; 970 existing.subtotal += parseFloat(seatObj.ticket_price) * seatData.length; 971 existing.formatted_subtotal = existing.subtotal; 972 } 973 }); 974 975 // Step 2: Update DOM attribute 976 $('#ep_event_booking_ticket').attr('data-ticket_options', JSON.stringify(ticketOptions)); 977 978 // Step 3: Rerun the cart render logic (simulate click behavior) 979 generateTicketHTML(ticketOptions); 980} 981 982 983 function ep_ls_update_bulk_cart_tickets(ticketsArray) { 984 const $ = jQuery; 985 986 let ep_added_ticket_option = $('#ep_event_booking_ticket').attr('data-ticket_options'); 987 ep_added_ticket_option = ep_added_ticket_option ? JSON.parse(ep_added_ticket_option) : []; 988 989 for (const ticket of ticketsArray) { 990 const ticket_id = ticket.id; 991 const single_ticket_detail_id = 'single_ticket_detail' + ticket_id; 992 const existingIndex = ep_added_ticket_option.findIndex(t => t.id === ticket_id); 993 994 if (existingIndex > -1) { 995 ep_added_ticket_option[existingIndex] = ticket; 996 } else { 997 ep_added_ticket_option.push(ticket); 998 } 999 1000 // Replace or append HTML 1001 const ticketHTML = generateTicketHTML(ticket); 1002 if ($('#ep_event_booking_ticket #' + single_ticket_detail_id).length > 0) { 1003 $('#ep_event_booking_ticket #' + single_ticket_detail_id).replaceWith(ticketHTML); 1004 } else { 1005 $('#ep_event_booking_ticket').append(ticketHTML); 1006 } 1007 1008 // Update seat info section 1009 $('#ep_single_ticket' + ticket_id + '_seat_info').empty(); 1010 1011 /** ð FIXED PART **/ 1012 if (Array.isArray(ticket.seats)) { 1013 for (const area of ticket.seats) { 1014 for (const seatObj of area.seat_data || []) { 1015 let amenities_html = ''; 1016 if (Array.isArray(seatObj.amenities) && seatObj.amenities.length > 0) { 1017 amenities_html = '<ul class="ep-seat-amenities" style="margin-top: 4px; font-size: 12px;">';
1018 seatObj.amenities.forEach(function (item) { 1019 amenities_html += '<li>'; 1020 if (item.icon) { 1021 amenities_html += `<img src="${item.icon}" alt="${item.title}" title="${item.title}" style="width:16px; height:16px; margin-right:4px; vertical-align:middle;" />`; 1022 } else { 1023 amenities_html += `<img src="${ep_als_front_ticket_object.amenity_icon}" alt="${item.title}" title="${item.title}" style="width:16px; height:16px; margin-right:4px; vertical-align:middle;" />`; 1024 } 1025 if (item.title) { 1026 amenities_html += `<span>${item.title}</span>`; 1027 } 1028 amenities_html += '</li>'; 1029 }); 1030 amenities_html += '</ul>'; 1031 } 1032 1033 const seatInfoHTML = ` 1034 <div class="ep-box-col-12 ep-text-end" id="ep_single_ticket${ticket_id}_seat_num_${seatObj.seat}"> 1035 ${seatObj.seat} 1036 ${amenities_html} 1037 </div>`; 1038 $('#ep_single_ticket' + ticket_id + '_seat_info').append(seatInfoHTML); 1039 } 1040 } 1041 } 1042 1043 1044 // Update ticket data attribute 1045 $('#ep_event_booking_ticket').attr('data-ticket_options', JSON.stringify(ep_added_ticket_option)); 1046 1047 // Recalculate totals 1048 ep_ls_calculate_tickets_total(); 1049 1050 // Enable checkout button 1051 $('#ep_als_single_event_checkout_btn').prop('disabled', false); 1052} 1053 } 1054 1055 1056 1057
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.