1function mpwem_qty_inperson(parent) { 2 let total_qty = 0; 3 parent.find('[name="option_qty[]"]').each(function () { 4 const $item = jQuery(this).closest('.mep_ticket_item'); 5 if (!$item.find('.mep-ticket-mode-badge--online').length) { 6 total_qty += parseInt(jQuery(this).val()) || 0; 7 } 8 }); 9 return total_qty; 10} 11function mpwem_price_calculation(parent) { 12 // alert(123); 13 try { 14 const total_qty = mpwem_qty(parent); 15 mpwem_attendee_management(parent, total_qty); 16 const target_summary = parent.find('.mpwem_total'); 17 let total = mpwem_price(parent); 18 if (total_qty > 0) { 19 parent.find('.mpwem_form_submit_area button').removeAttr('disabled'); 20 // For hybrid events, only show extra service when at least one in-person ticket is selected 21 const isHybrid = parent.find('.mep-ticket-mode-badge--online, .mep-ticket-mode-badge--inperson').length > 0; 22 const inPersonQty = isHybrid ? mpwem_qty_inperson(parent) : total_qty; 23 if (inPersonQty > 0) { 24 parent.find('.mpwem_ex_service').slideDown('fast'); 25 total += mpwem_ex_price(parent); 26 } else { 27 parent.find('.mpwem_ex_service').slideUp('fast'); 28 } 29 } else { 30 parent.find('.mpwem_ex_service').slideUp('fast'); 31 parent.find('.mpwem_form_submit_area button').attr('disabled', 'disabled'); 32 } 33 target_summary.html(mpwem_price_format(total)); 34 } catch (error) { 35 console.error('Error in price calculation:', error); 36 } 37} 38function mpwem_qty(parent) { 39 let total_qty = 0; 40 if (parent.find('.mpwem_seat_plan_area').length > 0) { 41 // Count selected seats 42 total_qty = parent.find('.mpwem_seat_available.mage_seat_selected').length; 43 } else { 44 // Sum up ticket quantities 45 parent.find('[name="option_qty[]"]').each(function () { 46 const qty = parseInt(jQuery(this).val()) || 0; 47 total_qty += qty; 48 }); 49 } 50 return total_qty; 51} 52function mpwem_qty_ex(parent) { 53 let total_qty = 0; 54 parent.find('[name="event_extra_service_qty[]"]').each(function () { 55 const qty = parseInt(jQuery(this).val()) || 0; 56 total_qty += qty; 57 }); 58 return total_qty; 59} 60function mpwem_price(parent) { 61 let total = 0; 62 if (parent.find('.mpwem_seat_plan_area').length > 0) { 63 parent.find('.mpwem_seat_available.mage_seat_selected').each(function () { 64 const seatPrice = parseFloat(jQuery(this).attr('data-seat_price')) || 0; 65 total += seatPrice; 66 }); 67 } else { 68 // Calculate from ticket quantities and prices 69 parent.find('[name="option_qty[]"]').each(function () { 70 const qty = parseInt(jQuery(this).val()) || 0; 71 const price = parseFloat(jQuery(this).attr('data-price')) || 0; 72 total += price * qty; 73 }); 74 } 75 return total; 76} 77function mpwem_ex_price(parent) { 78 let total = 0; 79 parent.find('[name="event_extra_service_qty[]"]').each(function () { 80 const ex_qty = parseInt(jQuery(this).val()) || 0; 81 const ex_price = parseFloat(jQuery(this).attr('data-price')) || 0; 82 total += ex_price * ex_qty; 83 }); 84 return total; 85} 86/** 87 * Attendee blocks with more than 4 fields get a 2-column layout class. 88 */ 89function mpwem_mark_attendee_form_columns(parent) { 90 const $scope = parent && parent.length ? parent : jQuery('.mpwem_registration_area'); 91 $scope.find('.mep_attendee_info .mep_form_item, .mep_attendee_info_hidden .mep_form_item').each(function () { 92 const $card = jQuery(this); 93 const fieldCount = $card.children('.mp_form_item').length; 94 $card.toggleClass('mep-form--cols-2', fieldCount > 4); 95 }); 96} 97/** 98 * Turn a freshly cloned attendee block back into real, submittable inputs. 99 * 100 * The blocks are cloned from .mep_attendee_info_hidden, whose controls are kept 101 * disabled (see mpwem_attendee_management), so every copy inherits that flag and 102 * has to be re-enabled once it lands in a real attendee container. 103 */ 104function mpwem_enable_attendee_clone(target) { 105 if (!target || !target.length) { 106 return; 107 } 108 target.find('.mep-template-disabled') 109 .removeClass('mep-template-disabled') 110 .prop('disabled', false) 111 .removeAttr('disabled'); 112} 113/** 114 * Make the booking form validatable, immediately before the browser validates it. 115 * 116 * Constraint validation runs *before* the submit event, so the submit handler further 117 * down cannot help here: when a required control sits in a display:none block the 118 * browser has nowhere to show the error, so it refuses to submit and tells the visitor 119 * nothing at all. The booking button just goes dead and only the console says why 120 * ("An invalid form control with name='user_name[]' is not focusable"). 121 * 122 * The two blocks that can hold such a control are both ones the plugin itself marks as 123 * inert - the clone source and a conditional field whose condition is not met - so only 124 * those are touched, and only when the control is still empty. A value the visitor 125 * typed is never disabled, because disabled controls are left out of the posted data. 126 * Anything that becomes visible later is re-enabled by the code that reveals it. 127 */ 128function mpwem_prepare_form_for_validation(parent) { 129 if (!parent || !parent.length) { 130 return; 131 } 132 parent.find('.mep_attendee_info_hidden').find('input, select, textarea').each(function () { 133 if (!jQuery(this).prop('disabled')) { 134 jQuery(this).addClass('mep-template-disabled').prop('disabled', true); 135 } 136 }); 137 parent.find('.dNone').find('input, select, textarea').each(function () { 138 if (!this.required || this.disabled || this.type === 'hidden') { 139 return; 140 } 141 if (jQuery.trim(this.value || '') !== '') { 142 return; 143 } 144 jQuery(this).prop('disabled', true); 145 }); 146} 147function mpwem_attendee_management(parent, total_qty) { 148 let form_target = parent.find('.mep_attendee_info'); 149 let same_attendee = parent.find('[name="mep_same_attendee"]').val(); 150 151 // Strip required attributes from hidden template inputs to avoid "invali
151d form control is not focusable" error 152 parent.find('.mep_attendee_info_hidden').find('input, select, textarea').each(function () { 153 if (jQuery(this).prop('required')) { 154 jQuery(this).removeAttr('required').addClass('mep-originally-required'); 155 } 156 // The hidden block is only a clone source, never something the visitor fills in, 157 // but it lives inside the registration form so its empty controls are posted 158 // alongside the real ones. Themes that move the attendee blocks further down the 159 // document - Horizon puts them in a drawer after </form> and re-attaches them with 160 // the form attribute, and form data is built in document order - then get that 161 // blank value at index 0 of every attendee array, which shifts every answer onto 162 // the wrong attendee and drops the last one's answers entirely. Disabled controls 163 // are left out of the submitted form data, so the template stops interfering. 164 if (!jQuery(this).prop('disabled')) { 165 jQuery(this).addClass('mep-template-disabled').attr('disabled', 'disabled'); 166 } 167 }); 168 169 if (form_target.length > 0 && total_qty > 0) { 170 if (same_attendee === 'yes' || same_attendee === 'must') { 171 form_target.slideDown('fast'); 172 } else { 173 let hidden_target = parent.find('.mep_attendee_info_hidden'); 174 if (parent.find('.mpwem_seat_plan_area').length > 0) { 175 let current_parent = parent.find('.mpwem_seat_plan_area'); 176 let form_length = current_parent.find('.mep_form_item').length; 177 form_target = current_parent.find('.mep_attendee_info'); 178 form_target.slideDown('fast'); 179 if (form_length !== total_qty) { 180 parent.find('.mpwem_seat_available.mage_seat_selected').each(function () { 181 let seat_name = jQuery(this).attr('data-seat-name'); 182 let ticket_name = jQuery(this).attr('data-seat-type'); 183 if (form_target.find('[data-seat_name="' + seat_name + '"]').length === 0) { 184 hidden_target.find('.mpwem_ticket_name').html(ticket_name); 185 hidden_target.find('.mep_form_item').attr('data-seat_name', seat_name); 186 hidden_target.find('.mpwem_ticket_count').html(seat_name).promise().done(function () { 187 form_target.append(hidden_target.html()); 188 mpwem_enable_attendee_clone(form_target); 189 form_target.find('.mep-originally-required').attr('required', 'required'); 190 }).promise().done(function () { 191 mpwem_load_date_picker(parent); 192 mpwem_mark_attendee_form_columns(parent); 193 }); 194 } 195 }).promise().done(function () { 196 form_length = form_target.find('.mep_form_item').length; 197 if (form_length !== total_qty) { 198 form_target.find('.mep_form_item').each(function () { 199 let seat_name = jQuery(this).attr('data-seat_name'); 200 if (parent.find('.mpwem_seat_available.mage_seat_selected[data-seat-name="' + seat_name + '"]').length === 0) { 201 jQuery(this).remove(); 202 } 203 }); 204 } 205 mpwem_mark_attendee_form_columns(parent); 206 }); 207 } else { 208 mpwem_mark_attendee_form_columns(parent); 209 } 210 } else { 211 parent.find('[name="option_qty[]"]').each(function () { 212 let current_parent = jQuery(this).closest('.mep_ticket_item'); 213 let qty = parseInt(jQuery(this).val()); 214 if (current_parent.find('[name="ticket_group_qty"]').length > 0) { 215 qty = qty * parseInt(current_parent.find('[name="ticket_group_qty"]').val()); 216 } 217 if (current_parent.find('[name="mep_group_qty"]').length > 0) { 218 qty = qty * parseInt(current_parent.find('[name="mep_group_qty"]').val()); 219 } 220 let form_length = current_parent.find('.mep_form_item').length; 221 form_target = current_parent.find('.mep_attendee_info'); 222 form_target.slideDown('fast'); 223 if (form_length !== qty) { 224 if (form_length > qty) { 225 for (let i = form_length; i > qty; i--) { 226 form_target.find('.mep_form_item:last-child').slide
226Up(250).remove(); 227 } 228 } else { 229 for (let i = form_length; i < qty; i++) { 230 let ticket_name = current_parent.find('[name="option_name[]"]').val(); 231 hidden_target.find('.mpwem_ticket_name').html(ticket_name); 232 hidden_target.find('.mpwem_ticket_count').html(i + 1).promise().done(function () { 233 form_target.append(hidden_target.html()).promise().done(function () { 234 mpwem_enable_attendee_clone(jQuery(this)); 235 jQuery(this).find('.mep-originally-required').attr('required', 'required'); 236 jQuery(this).find('.mp_form_item').each(function () { 237 let condition_type = jQuery(this).attr('data-depend'); 238 let current_ticket_name = jQuery(this).attr('data-condition-value'); 239 if (condition_type === 'mep_ticket_type' && current_ticket_name === ticket_name) { 240 jQuery(this).slideDown('fast').removeClass('dNone'); 241 } 242 }); 243 mpwem_mark_attendee_form_columns(parent); 244 }); 245 }).promise().done(function () { 246 mpwem_load_date_picker(parent); 247 mpwem_mark_attendee_form_columns(parent); 248 }); 249 } 250 } 251 } 252 }); 253 mpwem_mark_attendee_form_columns(parent); 254 } 255 } 256 mpwem_mark_attendee_form_columns(parent); 257 } else { 258 if (same_attendee === 'yes' || same_attendee === 'must') { 259 form_target.slideUp(250); 260 } else { 261 form_target.html('').slideUp(250); 262 } 263 } 264} 265(function ($) { 266 "use strict"; 267 $(document).ready(function () { 268 $('body').find('.mpwem_registration_area').each(function () { 269 mpwem_price_calculation($(this)); 270 mpwem_mark_attendee_form_columns($(this)); 271 }); 272 }); 273 $(document).on('change', '.mpwem_registration_area [name="mpwem_date_time"]', function () { 274 const parent = $(this).closest('.mpwem_registration_area'); 275 const time_slot = parent.find('#mpwem_time'); 276 if (time_slot.length > 0) { 277 const post_id = parent.find('[name="mpwem_post_id"]').val(); 278 const dates = parent.find('[name="mpwem_date_time"]').val(); 279 const target = parent.find('.mpwem_time_area'); 280 jQuery.ajax({ 281 type: 'POST', 282 url: mpwem_ajax_url, 283 data: { 284 action: "get_mpwem_time", 285 post_id: post_id, 286 dates: dates, 287 }, 288 beforeSend: function () { 289 mpwem_loader_xs(target); 290 }, 291 success: function (data) { 292 target.html(data).slideDown('fast').promise().done(function () { 293 const date = parent.find('[name="mpwem_time"]').val(); 294 get_mpwem_ticket(target, date); 295 }); 296 }, 297 error: function (xhr, status, error) { 298 console.error('Error loading time slots:', error); 299 target.html('<p class="error">Error loading time slots. Please try again.</p>'); 300 }, 301 complete: function () { 302 mpwem_loader_remove(target); 303 } 304 }); 305 } else { 306 get_mpwem_ticket($(this)); 307 } 308 }); 309 $(document).on('change', '.mpwem_registration_area [name="mpwem_time"]', function () { 310 let parent = $(this).closest('.mpwem_registration_area'); 311 let date = parent.find('[name="mpwem_time"]').val(); 312 get_mpwem_ticket($(this), date); 313 }); 314 function get_mpwem_ticket(current, date = '') { 315 let parent = current.closest('.mpwem_registration_area'); 316 let post_id = parent.find('[name="mpwem_post_id"]').val(); 317 let dates = date ? date : parent.find('[name="mpwem_date_time"]').val(); 318 let target = parent.find('.mpwem_booking_panel'); 319 jQuery.ajax({ 320 type: 'POST', 321 url: mpwem_ajax_url, 322 data: { 323 "action": "get_mpwem_ticket", 324 "post_id": post_id, 325 "dates": dates, 326 "backend_order": window.location.href.search("backend_order"), 327 }, 328 beforeSend: function () { 329 mpwem_loader_xs(target); 330 }, 331 success: function (data) { 332 // alert(dates); 333 target.html(data).slideDown('fast').promise().done(function () { 334 mpwem_load_seat_status(parent.closest('.mpwem_wrapper'),dates); 335 mep_change_date_status(parent.closest('.mpwem_wrapper'),dates); 336 mep_change_time_status(parent.closest('.mpwem_wrapper'),dates); 337 mpwem_price_calculation(parent); 338 }); 339 } 340 }); 341 } 342 function mpwem_load_seat_status(parent,dates) { 343 let target = parent.find('.mpwem_seat_status'); 344 if (target.length > 0) { 345 let post_id = parent.find('[name="mpwem_post_id"]').val(); 346 let dates = parent.find('[name="mpwem_date_time"]').val(); 347 jQuery.ajax({ 348 type: 'POST', 349 url: mpwem_script_var.url, 350 data: { 351 "action": "mpwem_load_seat_status", 352 "post_id": post_id, 353 "dates": dates, 354 "nonce": mpwem_script_var.nonce 355 }, 356 beforeSend: function () { 357 mpwem_loader_xs(target); 358 }, 359 success: function (data) { 360 target.html(data); 361 } 362 }); 363 } 364 } 365 function mep_change_date_status(parent,dates) { 366 let target = parent.find('.mep_date_status'); 367 368 let post_id = parent.find('[name="mpwem_post_id"]').val(); 369 //let dates = parent.find('[name="mpwem_date_time"]').val(); 370 jQuery.ajax({ 371 type: 'POST', 372 url: mpwem_script_var.url, 373 data: { 374 "action": "mep_change_date_status", 375 "post_id": post_id, 376 "dates": dates, 377 "nonce": mpwem_script_var.nonce 378 }, 379 beforeSend: function () { 380 mpwem_loader_xs(target); 381 }, 382 success: function (data) { 383 target.html(data); 384 } 385 }); 386 387 } 388 function mep_change_time_status(parent,dates) { 389 let target = parent.find('.mep_time_status'); 390 391 let post_id = parent.find('[name="mpwem_post_id"]').val(); 392 //let dates = parent.find('[name="mpwem_date_time"]').val(); 393 jQuery.ajax({ 394 type: 'POST', 395 url: mpwem_script_var.url, 396 data: { 397 "action": "mep_change_time_status", 398 "post_id": post_id, 399 "dates": dates, 400 "nonce": mpwem_script_var.nonce 401 }, 402 beforeSend: function () { 403 mpwem_loader_xs(target); 404 }, 405 success: function (data) { 406 target.html(data); 407 } 408 }); 409 410 } 411 $(document).on("click", "div.mpwem_style .decQty, div.mpwem_style .incQty", function () { 412 let parent = $(this).closest('.mpwem_registration_area'); 413 let current = $(this); 414 if (!current.hasClass('mpDisabled')) { 415 let target = current.closest('.qtyIncDec').find('input'); 416 let newValue = parseInt(target.val()) || 0; 417 let min = parseInt(target.attr('min')) || 0; 418 let max = parseInt(target.attr('max')) || Infinity; 419 let minQty = parseInt(target.attr('data-min-qty')) || 0; 420 if (current.hasClass('incQty')) { 421 newValue = newValue + 1; 422 if (newValue < min) { 423 newValue = min; 424 } 425 } else { 426 newValue = newValue - 1; 427 if (newValue < min) { 428 newValue = 0; 429 } 430 } 431 if (minQty > 0) { 432 newValue = Math.max(newValue, min); 433 } 434 newValue = Math.min(newValue, max); 435 target.val(newValue); 436 parent.find('.qtyIncDec').each(function () {
437 let $this = $(this); 438 $this.find('.incQty, .decQty').removeClass('mpDisabled'); 439 let loop_target = $(this).find('input'); 440 let loop_value = parseInt(loop_target.val()) || 0; 441 //let loop_min = parseInt(loop_target.attr('min')) || 0; 442 let loop_max = parseInt(loop_target.attr('max')) || Infinity; 443 let loop_minQty = parseInt(loop_target.attr('data-min-qty')) || 0; 444 if (loop_value >= loop_max) { 445 $this.find('.incQty').addClass('mpDisabled'); 446 } 447 if (loop_value <= loop_minQty) { 448 $this.find('.decQty').addClass('mpDisabled'); 449 } 450 }).promise().done(function () { 451 target.trigger('change').trigger('input'); 452 }); 453 } 454 }); 455 $(document).on('change', '.mpwem_registration_area [name="option_qty[]"]', function () { 456 let parent = $(this).closest('.mpwem_registration_area'); 457 let qty = $(this).val(); 458 let total_qty = mpwem_qty(parent); 459 if (parent.find('[name="mepgq_max_qty"]').length > 0) { 460 let max_qty_gq = parseInt(parent.find('[name="mepgq_max_qty"]').val()); 461 if (max_qty_gq > 0 && total_qty > max_qty_gq) { 462 qty = qty - total_qty + max_qty_gq; 463 $(this).val(qty); 464 mpwem_price_calculation(parent); 465 } else { 466 mpwem_price_calculation(parent); 467 } 468 } else if (parent.find('[name="mepmm_min_qty"]').length > 0) { 469 let max_qty = parseInt(parent.find('[name="mepmm_max_qty"]').val()); 470 if (max_qty > 0 && total_qty > max_qty) { 471 qty = qty - total_qty + max_qty; 472 $(this).val(qty); 473 mpwem_price_calculation(parent); 474 } else { 475 mpwem_price_calculation(parent); 476 } 477 } else { 478 mpwem_price_calculation(parent); 479 } 480 }); 481 $(document).on("click", ".mpwem_book_now", function (e) { 482 e.preventDefault(); 483 484 const $wrap = $(this).closest('.mpwem_summery'); 485 const alreadyInCart = 0; 486 if (alreadyInCart === 1 || alreadyInCart === '1') { 487 alert('This product is already in your cart.'); 488 return false; 489 }else { 490 let parent = $(this).closest('.mpwem_registration_area'); 491 let total_qty = mpwem_qty(parent); 492 if (total_qty > 0) { 493 if (parent.find('[name="mepmm_min_qty"]').length > 0) { 494 let min_qty = parseInt(parent.find('[name="mepmm_min_qty"]').val()); 495 if (total_qty < min_qty) { 496 alert('must buy minimum number of ticket : ' + min_qty); 497 } else { 498 mpwem_prepare_form_for_validation(parent); 499 parent.find('.mpwem_add_to_cart').trigger('click'); 500 } 501 } else { 502 mpwem_prepare_form_for_validation(parent); 503 parent.find('.mpwem_add_to_cart').trigger('click'); 504 } 505 } else { 506 alert('Please Select Ticket Type'); 507 let currentTarget = $(this).closest('.mpwem_registration_area').find('[name="option_qty[]"]'); 508 currentTarget.addClass('error'); 509 return false; 510 } 511 } 512 }); 513 /** 514 * Last line of defence before the booking is posted: whichever code path cloned the 515 * attendee blocks, the clone source must not reach the server and every real attendee 516 * control must. Without this the attendee answers can be posted one index out of step 517 * (see mpwem_attendee_management), which silently files each answer against the wrong 518 * attendee and loses the last attendee's answers altogether. 519 */ 520 $(document).on('submit', 'form#mpwem_registration', function () { 521 $(this).find('.mep_attendee_info_hidden').find('input, select, textarea').prop('disabled', true); 522 mpwem_enable_attendee_clone($('.mep_attendee_info')); 523 }); 524 $(document).on('change', '.mpwem_registration_area [name="event_extra_service_qty[]"]', function () { 525 let parent = $(this).closest('.mpwem_registration_area'); 526 if (parent.find('[name="mepgq_max_ex_qty"]').length > 0) { 527 let qty = $(this).val(); 528 let total_qty = mpwem_qty_ex(parent); 529 let max_qty_gq = parseInt(parent.find('[name="mepgq_max_ex_qty"]').val()); 530 if (total_qty > max_qty_gq) { 531 qty = qty - total_qty + max_qty_gq; 532 $(this).val(qty); 533 mpwem_price_calculation(parent); 534 } else { 535 mpwem_price_calculation(parent); 536 } 537 } else { 538 mpwem_price_calculation(parent); 539 } 540 }); 541 /************File Upload*************/ 542 $(document).on('change', '.mep_form_item .mep_file_item input[type="file"]', function (e) { 543 let parent = $(this).closest('.mep_file_item'); 544 let input = this; 545 let url = input.value; 546 let ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase(); 547 if (input.files && input.files[0] && (ext === "gif" || ext === "png" || ext === "jpg" || ext === "pdf")) { 548 if (input.files[0].size <= 1024000) { 549 let reader = new FileReader(); 550 reader.onload = function (e) { 551 if (ext === "pdf") { 552 parent.find('.attach_file_view img').slideUp(250); 553 parent.find('.attach_file_view span').slide
553Up(250); 554 parent.find('.attach_file_view iframe').attr('src', e.target.result).slideDown(250); 555 } else { 556 parent.find('.attach_file_view iframe').slideUp(250); 557 parent.find('.attach_file_view span').slideUp(250); 558 parent.find('.attach_file_view img').attr('src', e.target.result).slideDown(250); 559 } 560 } 561 reader.readAsDataURL(input.files[0]); 562 } else { 563 alert('Maximum size 1MB'); 564 parent.find('.attach_file_view img').slideUp(250); 565 parent.find('.attach_file_view span').slideDown(250); 566 parent.find('.attach_file_view iframe').slideUp(250); 567 $(this).val(''); 568 } 569 } else { 570 parent.find('.attach_file_view img').slideUp(250); 571 parent.find('.attach_file_view span').slideDown(250); 572 parent.find('.attach_file_view iframe').slideUp(250); 573 $(this).val(''); 574 } 575 }); 576 /************conditional form*************/ 577 function mep_get_condition_trigger_value($el) { 578 if ($el.is('select')) { 579 let $opt = $el.find('option:selected'); 580 return ($opt.attr('data-target-child-id') || $el.val() || '').toString(); 581 } 582 return ($el.val() || '').toString(); 583 } 584 585 function mep_condition_value_matches(selected, expected) { 586 selected = (selected || '').toString().trim(); 587 expected = (expected || '').toString().trim(); 588 if (!expected) { 589 return false; 590 } 591 if (!selected) { 592 return false; 593 } 594 if (selected.indexOf(',') !== -1) { 595 return selected.split(',').map(function (part) { 596 return part.trim(); 597 }).indexOf(expected) !== -1; 598 } 599 return selected === expected; 600 } 601 602 function mep_apply_field_conditions($trigger) { 603 let condition_id = $trigger.attr('data-target-condition-id'); 604 if (!condition_id) { 605 return; 606 } 607 let selected_value = mep_get_condition_trigger_value($trigger); 608 // Scope to the attendee block (siblings), not the parent field wrapper. 609 let $scope = $trigger.closest('.mep_attendee_info, .mep_attendee_info_hidden'); 610 if (!$scope.length) { 611 $scope = $trigger.closest('.mpwem_registration_area, .mpwem_style'); 612 } 613 if (!$scope.length) { 614 $scope = $trigger.closest('form'); 615 } 616 if (!$scope.length) { 617 $scope = jQuery(document); 618 } 619 $scope.find('[data-condition-id="' + condition_id + '"]').each(function () { 620 let $item = jQuery(this); 621 let depend = ($item.attr('data-depend') || '').toString(); 622 if (depend === 'mep_ticket_type') { 623 return; 624 } 625 let condition_value = $item.attr('data-condition-value'); 626 if (!condition_value) { 627 return; 628 } 629 if (mep_condition_value_matches(selected_value, condition_value)) { 630 $item.removeClass('dNone').stop(true, true).slideDown('fast'); 631 } else { 632 $item.addClass('dNone').stop(true, true).slideUp('fast'); 633 } 634 }); 635 } 636 637 $(document).on('change', '.mep_form_item [data-target-condition-id]', function () { 638 mep_apply_field_conditions(jQuery(this)); 639 }); 640}(jQuery)); 641//*****************************Related Event***********************************// 642(function ($) { 643 "use strict"; 644 function mpwem_related_refresh_slider($slider) { 645 if (!$slider || !$slider.length || !$slider.hasClass('slick-initialized')) { 646 return; 647 } 648 // Clear list-template inline % widths so slick can own exact pixel widths. 649 $slider.find('.slick-slide, .filter_item.mep_event_card').each(function () { 650 var el = this; 651 if (el.style && el.style.width && String(el.style.width).indexOf('%') !== -1) { 652 el.style.removeProperty('width'); 653 } 654 }); 655 $slider.slick('setPosition'); 656 } 657 658 $(document).ready(function () { 659 $('.mpwem_related_area').each(function () { 660 var $area = $(this); 661 var $slider = $area.find('.related_item'); 662 if (!$slider.length || $slider.hasClass('slick-initialized')) { 663 return; 664 } 665 666 // Drop grid % widths before init so slides don't overflow / look cut. 667 $slider.find('.filter_item.mep_event_card, .mep-event-list-loop').each(function () { 668 this.style.removeProperty('width'); 669 }); 670 671 var slideCount = $slider.children('.filter_item, .mep-event-list-loop').length; 672 var desktopShow = Math.min(3, Math.max(1, slideCount)); 673 var tabletShow = Math.min(2, desktopShow); 674 var mobileShow = 1; 675 676 $slider.slick({ 677 dots: false, 678 arrows: true, 679 prevArrow: $area.find('.related_prev'), 680 nextArrow: $area.find('.related_next'), 681 infinite: slideCount > desktopShow, 682 centerMode: false, 683 variableWidth: false, 684 autoplay: false, 685 autoplaySpeed: 2000,
686 centerPadding: '0px', 687 slidesToShow: desktopShow, 688 slidesToScroll: 1, 689 responsive: [ 690 { 691 breakpoint: 1024, 692 settings: { 693 slidesToShow: tabletShow, 694 slidesToScroll: 1, 695 infinite: slideCount > tabletShow, 696 dots: false, 697 centerMode: false, 698 variableWidth: false 699 } 700 }, 701 { 702 breakpoint: 767, 703 settings: { 704 slidesToShow: mobileShow, 705 slidesToScroll: 1, 706 infinite: slideCount > mobileShow, 707 dots: false, 708 centerMode: false, 709 variableWidth: false 710 } 711 } 712 ] 713 }).promise().done(function () { 714 $area.removeClass('on_load_off'); 715 mpwem_related_refresh_slider($slider); 716 // Re-apply lazy bg images after slick has real slide widths (incl. clones). 717 $slider.find('.mep_list_thumb [data-bg-image]').each(function () { 718 var $img = $(this); 719 var bg_url = $img.data('bg-image'); 720 if (!bg_url) { 721 return; 722 } 723 if ($img.css('background-image') === 'none' || !$img.css('background-image')) { 724 $img.css({ 725 'background-image': 'url("' + bg_url + '")', 726 'background-size': 'cover', 727 'background-position': 'center center', 728 'background-repeat': 'no-repeat' 729 }); 730 } 731 }); 732 if (typeof mpwem_load_bg_image === 'function') { 733 mpwem_load_bg_image(); 734 } 735 // Recalc after fonts/images settle so the 3rd card isn't clipped. 736 setTimeout(function () { 737 mpwem_related_refresh_slider($slider); 738 }, 50); 739 $(window).on('load.mpwemRelated', function () { 740 mpwem_related_refresh_slider($slider); 741 }); 742 }); 743 }); 744 }); 745 746 $(window).on('resize.mpwemRelated', function () { 747 $('.mpwem_related_area .related_item.slick-initialized').each(function () { 748 mpwem_related_refresh_slider($(this)); 749 }); 750 }); 751}(jQuery)); 752//*****************************Event list***********************************// 753(function ($) { 754 "use strict"; 755 $(document).on('click', 'button.mpwem_get_date_list', function () { 756 let $this = $(this); 757 let parent = $this.closest('.mpwem_list_date_list'); 758 let target = parent.find('.date_list_area'); 759 if (!target.length) { 760 return; 761 } 762 if (target.find('.date_item').length === 0) { 763 let event_id = $this.data('event-id'); 764 if (!event_id) { 765 return; 766 } 767 jQuery.ajax({ 768 type: 'POST', 769 url: mpwem_script_var.url, 770 data: { 771 "action": "mpwem_get_date_list", 772 "post_id": event_id, 773 "nonce": mpwem_script_var.nonce 774 }, 775 beforeSend: function () { 776 mpwem_loader_xs($this); 777 }, 778 success: function (data) { 779 target.html(data); 780 target.addClass('open_list mActive').show(); 781 mpwem_loader_remove($this); 782 } 783 }); 784 } 785 }); 786 787 $(document).on('click', 'button.mep_event_list_grid', function () { 788 let $this = $(this); 789 let parent = $this.closest('.list_with_filter_section'); 790 let target = parent.find('.mage_grid_box'); 791 let target_data = parent.find('.all_filter_item'); 792let id=target_data.attr('data-unq-id'); 793let style='grid'; 794let column=target_data.attr('data-column'); 795let cat=target_data.attr('data-cat'); 796let org=target_data.attr('data-org'); 797let tag=target_data.attr('data-tag'); 798let city=target_data.attr('data-city'); 799let country=target_data.attr('data-country'); 800let status=target_data.attr('data-status'); 801let year=target_data.attr('data-year'); 802let sort=target_data.attr('data-sort'); 803let show=target_data.attr('data-show'); 804let pagination=target_data.attr('data-pagination'); 805let pagination_style=target_data.attr('data-pagination-style'); 806 jQuery.ajax({ 807 type: 'POST', 808 url: mpwem_script_var.url, 809 data: { 810 "action": "mep_gat_event_list_all", 811 "id": id, 812 "style": style, 813 "column": column, 814 "cat": cat, 815 "org": org, 816 "tag": tag, 817 "city": city, 818 "country": country, 819 "status": status, 820 "year": year, 821 "sort": sort, 822 "show": show, 823 "pagination": pagination, 824 "pagination_style": pagination_style, 825 "nonce": mpwem_script_var.nonce 826 }, 827 beforeSend: function () { 828 showLoader(); 829 }, 830 success: function (data) { 831 hideLoader(); 832 target.html(data); 833 if (typeof mepCalendarInit === 'function') { 834 mepCalendarInit(); 835 } 836 target.find('[data-bg-image]:visible').each(function () { 837 let target = jQuery(this); 838 if (target.closest('.sliderAllItem').length === 0) { 839 let width = target.outerWidth(); 840 let height = target.outerHeight(); 841 if (target.css('background-image') === 'none' || width === 0 || height === 0) { 842 let bg_url = target.data('bg-image'); 843 if (!bg_url || bg_url.width === 0 || bg_url.width === 'undefined') { 844 bg_url = mpwem_empty_image_url; 845 } 846 mpwem_resize_bg_image_area(target, bg_url); 847 target.css('background-image', 'url("' + bg_url + '")').promise().done(function () { 848 mpwem_loader_remove(jQuery(this)); 849 }); 850 } 851 } 852 853 }); 854 parent.find('.mep_event_list_grid').addClass('active'); 855 parent.find('.mep_event_list_list').removeClass('active'); 856 parent.find('.mep_event_list_calender').removeClass('active'); 857 if(parent.find('.mep_event_list_today').hasClass( 'active' )){ 858 parent.find('.mep_event_list_today').trigger('click'); 859 } 860 if(parent.find('.mep_event_list_this_month').hasClass( 'active' )){ 861 parent.find('.mep_event_list_this_month').trigger('click'); 862 } 863 } 864 }); 865 866 }); 867 $(document).on('click', 'button.mep_event_list_list', function () {
868 let $this = $(this); 869 let parent = $this.closest('.list_with_filter_section'); 870 let target = parent.find('.mage_grid_box'); 871 let target_data = parent.find('.all_filter_item'); 872let id=target_data.attr('data-unq-id'); 873let style='list'; 874let column=target_data.attr('data-column'); 875let cat=target_data.attr('data-cat'); 876let org=target_data.attr('data-org'); 877let tag=target_data.attr('data-tag'); 878let city=target_data.attr('data-city'); 879let country=target_data.attr('data-country'); 880let status=target_data.attr('data-status'); 881let year=target_data.attr('data-year'); 882let sort=target_data.attr('data-sort'); 883let show=target_data.attr('data-show'); 884let pagination=target_data.attr('data-pagination'); 885let pagination_style=target_data.attr('data-pagination-style'); 886 jQuery.ajax({ 887 type: 'POST', 888 url: mpwem_script_var.url, 889 data: { 890 "action": "mep_gat_event_list_all", 891 "id": id, 892 "style": style, 893 "column": column, 894 "cat": cat, 895 "org": org, 896 "tag": tag, 897 "city": city, 898 "country": country, 899 "status": status, 900 "year": year, 901 "sort": sort, 902 "show": show, 903 "pagination": pagination, 904 "pagination_style": pagination_style, 905 "nonce": mpwem_script_var.nonce 906 }, 907 beforeSend: function () { 908 showLoader(); 909 }, 910 success: function (data) { 911 hideLoader(); 912 target.html(data); 913 target.find('[data-bg-image]:visible').each(function () { 914 let target = jQuery(this); 915 if (target.closest('.sliderAllItem').length === 0) { 916 let width = target.outerWidth(); 917 let height = target.outerHeight(); 918 if (target.css('background-image') === 'none' || width === 0 || height === 0) { 919 let bg_url = target.data('bg-image'); 920 if (!bg_url || bg_url.width === 0 || bg_url.width === 'undefined') { 921 bg_url = mpwem_empty_image_url; 922 } 923 mpwem_resize_bg_image_area(target, bg_url); 924 target.css('background-image', 'url("' + bg_url + '")').promise().done(function () { 925 mpwem_loader_remove(jQuery(this)); 926 }); 927 } 928 } 929 930 }); 931 parent.find('.mep_event_list_list').addClass('active'); 932 parent.find('.mep_event_list_grid').removeClass('active'); 933 parent.find('.mep_event_list_calender').removeClass('active'); 934 if(parent.find('.mep_event_list_this_month').hasClass( 'active' )){ 935 parent.find('.mep_event_list_this_month').trigger('click'); 936 } 937 } 938 }); 939 940 }); 941 $(document).on('click', 'button.mep_event_list_calender', function () { 942 let $this = $(this); 943 let parent = $this.closest('.list_with_filter_section'); 944 let target = parent.find('.mage_grid_box'); 945 let target_data = parent.find('.all_filter_item'); 946 let id=target_data.attr('data-unq-id'); 947 let cat=target_data.attr('data-cat'); 948 let org=target_data.attr('data-org'); 949 let tag=target_data.attr('data-tag'); 950 let city=target_data.attr('data-city'); 951 let country=target_data.attr('data-country'); 952 let status=target_data.attr('data-status'); 953 let year=target_data.attr('data-year'); 954 jQuery.ajax({ 955 type: 'POST', 956 url: mpwem_script_var.url, 957 data: { 958 "action": "mep_gat_event_calender", 959 "nonce": mpwem_script_var.nonce, 960 "cat": cat, 961 "org": org, 962 "tag": tag, 963 "city": city, 964 "country": country, 965 "status": status, 966 "year": year 967 }, 968 beforeSend: function () { 969 showLoader(); 970 }, 971 success: function (data) { 972 hideLoader(); 973 target.html(data); 974 target.find('[data-bg-image]:visible').each(function () { 975 let target = jQuery(this); 976 if (target.closest('.sliderAllItem').length === 0) { 977 let width = target.outerWidth(); 978 let height = target.outerHeight(); 979 if (target.css('background-image') === 'none' || width === 0 || height === 0) { 980 let bg_url = target.data('bg-image'); 981 if (!bg_url || bg_url.width === 0 || bg_url.width === 'undefined') { 982 bg_url = mpwem_empty_image_url; 983 } 984 mpwem_resize_bg_image_area(target, bg_url); 985 target.css('background-image', 'url("' + bg_url + '")').promise().done(function () { 986 mpwem_loader_remove(jQuery(this)); 987 }); 988 } 989 } 990 991 }); 992 parent.find('.mep_event_list_list').removeClass('active'); 993 parent.find('.mep_event_list_grid').removeClass('active'); 994 parent.find('.mep_event_list_calender').addClass('active'); 995 } 996 }); 997 998 }); 999 1000 $(document).on('click', 'button.mep_event_list_all', function () {
1001 let $this = $(this); 1002 let parent = $this.closest('.list_with_filter_section'); 1003 let target = parent.find('.mage_grid_box'); 1004 let target_data = parent.find('.all_filter_item'); 1005 var items = jQuery('.mep-event-list-loop'); 1006 items.each(function () {jQuery(this).show();}); 1007 parent.find('.pagination_area').slideUp('fast'); 1008 parent.find('.mep_event_list_all').addClass('active'); 1009 parent.find('.mep_event_list_today').removeClass('active'); 1010 parent.find('.mep_event_list_this_week').removeClass('active'); 1011 parent.find('.mep_event_list_this_month').removeClass('active'); 1012 1013 }); 1014 1015 $(document).on('click', 'button.mep_event_list_today', function () { 1016 let $this = $(this); 1017 let parent = $this.closest('.list_with_filter_section'); 1018 let target = parent.find('.mage_grid_box'); 1019 let target_data = parent.find('.all_filter_item'); 1020 1021 var items = jQuery('.mep-event-list-loop'); 1022 let exit=0; 1023 items.each(function () { 1024 let today=$this.attr('data-today'); 1025 var date = jQuery(this).data('date'); 1026 let date1 = new Date(date); 1027 let date2 = new Date(date); 1028 if (date===today) { 1029 jQuery(this).show(); 1030 exit=1; 1031 } else { 1032 jQuery(this).hide(); 1033 } 1034 }); 1035 if(exit===0){ 1036 parent.find('.no_event_found').show(); 1037 }else{ 1038 parent.find('.no_event_found').hide(); 1039 } 1040 parent.find('.pagination_area').slideUp('fast'); 1041 parent.find('.mep_event_list_all').removeClass('active'); 1042 parent.find('.mep_event_list_this_week').removeClass('active'); 1043 parent.find('.mep_event_list_this_month').removeClass('active'); 1044 parent.find('.mep_event_list_today').addClass('active'); 1045 }); 1046 $(document).on('click', 'button.mep_event_list_this_month', function () { 1047 let $this = $(this); 1048 let parent = $this.closest('.list_with_filter_section'); 1049 1050 var items = jQuery('.mep-event-list-loop'); 1051 let today = new Date(); 1052 let year = today.getFullYear(); 1053 let month = today.getMonth(); 1054 let firstDay = new Date(year, month, 1); 1055 let lastDay = new Date(year, month + 1, 0); 1056 //alert(lastDay); 1057 let exit=0; 1058 items.each(function () { 1059 var date = jQuery(this).data('date'); 1060 let date1 = new Date(date); 1061 if (date1 >= firstDay && date1 <= lastDay) { 1062 jQuery(this).show(); 1063 exit=1; 1064 } else { 1065 jQuery(this).hide(); 1066 } 1067 }); 1068 if(exit===0){ 1069 parent.find('.no_event_found').show(); 1070 }else{ 1071 parent.find('.no_event_found').hide(); 1072 } 1073 parent.find('.pagination_area').slideUp('fast'); 1074 parent.find('.mep_event_list_all').removeClass('active'); 1075 parent.find('.mep_event_list_this_week').removeClass('active'); 1076 parent.find('.mep_event_list_today').removeClass('active'); 1077 parent.find('.mep_event_list_this_month').addClass('active'); 1078 }); 1079 $(document).on('click', 'button.mep_event_list_this_week', function () { 1080 let $this = $(this); 1081 let parent = $this.closest('.list_with_filter_section'); 1082 let target = parent.find('.mage_grid_box'); 1083 let target_data = parent.find('.all_filter_item'); 1084 1085 var items = jQuery('.mep-event-list-loop'); 1086 let exit=0; 1087 items.each(function () { 1088 let week=$this.attr('data-week'); 1089 let today=parent.find('.mep_event_list_today').attr('data-today'); 1090 var date = jQuery(this).data('date'); 1091 let date1 = new Date(date); 1092 let date2 = new Date(today); 1093 let date3 = new Date(week); 1094 if (date1>=date2 && date1<=date3) { 1095 jQuery(this).show(); 1096 exit=1; 1097 } else { 1098 jQuery(this).hide(); 1099 } 1100 }); 1101 if(exit===0){ 1102 parent.find('.no_event_found').show(); 1103 }else{ 1104 parent.find('.no_event_found').hide(); 1105 }
1106 parent.find('.pagination_area').slideUp('fast'); 1107 parent.find('.mep_event_list_all').removeClass('active'); 1108 parent.find('.mep_event_list_today').removeClass('active'); 1109 parent.find('.mep_event_list_this_month').removeClass('active'); 1110 parent.find('.mep_event_list_this_week').addClass('active'); 1111 }); 1112 $(document).on('change', 'input[name="filter_with_start_date"]', function (e) { 1113 e.preventDefault(); 1114 let $this = $(this); 1115 let parent = $this.closest('.list_with_filter_section'); 1116 let target = parent.find('.mage_grid_box'); 1117 let target_data = parent.find('.all_filter_item'); 1118 let start_date=$this.val(); 1119 //alert(start_date); 1120 let end_date=parent.find('input[name="filter_with_end_date"]').val(); 1121 let exit=0; 1122 if(start_date && end_date) { 1123 var items = jQuery('.mep-event-list-loop'); 1124 items.each(function () { 1125 let week = $this.attr('data-week'); 1126 let today = parent.find('.mep_event_list_today').attr('data-today'); 1127 var date = jQuery(this).data('date'); 1128 let date1 = new Date(date); 1129 let date2 = new Date(start_date); 1130 let date3 = new Date(end_date); 1131 if (date1 >= date2 && date1 <= date3) { 1132 jQuery(this).show(); 1133 exit=1; 1134 } else { 1135 jQuery(this).hide(); 1136 } 1137 }); 1138 if(exit===0){ 1139 parent.find('.no_event_found').show(); 1140 }else{ 1141 parent.find('.no_event_found').hide(); 1142 } 1143 parent.find('.pagination_area').slideUp('fast'); 1144 parent.find('.mep_event_list_all').removeClass('active'); 1145 parent.find('.mep_event_list_today').removeClass('active'); 1146 parent.find('.mep_event_list_this_month').removeClass('active'); 1147 parent.find('.mep_event_list_this_week').removeClass('active'); 1148 } 1149 }); 1150 $(document).on('change', 'input[name="filter_with_end_date"]', function (e) { 1151 e.preventDefault(); 1152 let $this = $(this); 1153 let parent = $this.closest('.list_with_filter_section'); 1154 let target = parent.find('.mage_grid_box'); 1155 let target_data = parent.find('.all_filter_item'); 1156 let start_date=parent.find('input[name="filter_with_start_date"]').val(); 1157 let end_date=$this.val(); 1158 // alert(end_date); 1159 let exit=0; 1160 if(start_date && end_date) { 1161 var items = jQuery('.mep-event-list-loop'); 1162 items.each(function () { 1163 let week = $this.attr('data-week'); 1164 let today = parent.find('.mep_event_list_today').attr('data-today'); 1165 var date = jQuery(this).data('date'); 1166 let date1 = new Date(date); 1167 let date2 = new Date(start_date); 1168 let date3 = new Date(end_date); 1169 if (date1 >= date2 && date1 <= date3) { 1170 jQuery(this).show(); 1171 exit=1; 1172 } else { 1173 jQuery(this).hide(); 1174 } 1175 }); 1176 if(exit===0){ 1177 parent.find('.no_event_found').show(); 1178 }else{ 1179 parent.find('.no_event_found').hide(); 1180 } 1181 parent.find('.pagination_area').slideUp('fast'); 1182 parent.find('.mep_event_list_all').removeClass('active'); 1183 parent.find('.mep_event_list_today').removeClass('active'); 1184 parent.find('.mep_event_list_this_month').removeClass('active'); 1185 parent.find('.mep_event_list_this_week').removeClass('active'); 1186 } 1187 }); 1188 // Advanced Filter Panel Toggle 1189 $(document).on('click', 'button.mep_event_list_filter_toggle', function () { 1190 let $this = $(this); 1191 let parent = $this.closest('.list_with_filter_section'); 1192 let panel = parent.find('.mep_event_filter_panel'); 1193 panel.slideToggle('fast'); 1194 $this.toggleClass('active'); 1195 // Initialize datepickers with event dates on first open 1196 if ( ! panel.data('datepicker-init') ) { 1197 let datesAttr = panel.attr('data-event-dates'); 1198 let availableDates = []; 1199 try { 1200 availableDates = datesAttr ? JSON.parse(datesAttr) : []; 1201 } catch (e) { 1202 availableDates = []; 1203 } 1204 let $startDate = panel.find('input[name="filter_with_start_date"]'); 1205 let $endDate = panel.find('input[name="filter_with_end_date"]'); 1206 function initDatepicker($el) { 1207 $el.datepicker('destroy'); 1208 $el.datepicker({ 1209 dateFormat: 'mm/dd/yy', 1210 beforeShowDay: function (date) { 1211 let m = date.getMonth() + 1; 1212 let d = date.getDate(); 1213 let y = date.getFullYear(); 1214 let dateStr = ('0' + m).slice(-2) + '/' + ('0' + d).slice(-2) + '/' + y; 1215 if ( availableDates.indexOf(dateStr) !== -1 ) { 1216 return [true, '', 'Available']; 1217 } 1218 return [false, '', 'Unavailable']; 1219 }, 1220 onSelect: function (selectedDate) { 1221 if ( $(this).attr('name') === 'filter_with_start_date' ) { 1222 $endDate.datepicker('option', 'minDate', selectedDate); 1223 $endDate.trigger('change'); 1224 } else if ( $(this).attr('name') === 'filter_with_end_date' ) { 1225 $startDate.datepicker('option', 'maxDate', selectedDate); 1226 $startDate.trigger('change'); 1227 } 1228 //applyAllFilters(); 1229 } 1230 }); 1231 } 1232 initDatepicker($startDate); 1233 initDatepicker($endDate); 1234 panel.data('datepicker-init', true); 1235 } 1236 }); 1237 1238 // Clear All Filters 1239 $(document).on('click', 'button.mep_event_filter_clear', function () { 1240 let parent = $(this).closest('.mep_event_filter_panel'); 1241 parent.find('input[name="filter_with_title"]').val(''); 1242 parent.find('input[name="filter_with_start_date"]').val(''); 1243 parent.find('input[name="filter_with_end_date"]').val(''); 1244 parent.find('select[name="filter_with_category"]').val(''); 1245 parent.find('select[name="filter_with_organizer"]').val(''); 1246 parent.find('select[name="filter_with_city"]').val(''); 1247 parent.find('select[name="filter_with_state"]').val(''); 1248 // Also reset legacy single date filter if it exists 1249 parent.find('input[name="filter_with_date"]').val(''); 1250 // Show all items 1251 jQuery('.mep-event-list-loop').each(function () { 1252 jQuery(this).show(); 1253 }); 1254 parent.find('.no_event_found').hide(); 1255 // Update count display 1256 var totalItems = jQuery('.mep-event-list-loop').length; 1257 jQuery('.qty_count').text(totalItems); 1258 }); 1259 $(document).on('click', 'button.mep_event_filter_close', function () {
1260 let $this = $(this); 1261 let parent = $this.closest('.list_with_filter_section'); 1262 let panel = parent.find('.mep_event_filter_panel'); 1263 panel.slideToggle('fast'); 1264 $this.toggleClass('active'); 1265 // Initialize datepickers with event dates on first open 1266 if ( ! panel.data('datepicker-init') ) { 1267 let datesAttr = panel.attr('data-event-dates'); 1268 let availableDates = []; 1269 try { 1270 availableDates = datesAttr ? JSON.parse(datesAttr) : []; 1271 } catch (e) { 1272 availableDates = []; 1273 } 1274 let $startDate = panel.find('input[name="filter_with_start_date"]'); 1275 let $endDate = panel.find('input[name="filter_with_end_date"]'); 1276 function initDatepicker($el) { 1277 $el.datepicker('destroy'); 1278 $el.datepicker({ 1279 dateFormat: 'mm/dd/yy', 1280 beforeShowDay: function (date) { 1281 let m = date.getMonth() + 1; 1282 let d = date.getDate(); 1283 let y = date.getFullYear(); 1284 let dateStr = ('0' + m).slice(-2) + '/' + ('0' + d).slice(-2) + '/' + y; 1285 if ( availableDates.indexOf(dateStr) !== -1 ) { 1286 return [true, '', 'Available']; 1287 } 1288 return [false, '', 'Unavailable']; 1289 }, 1290 onSelect: function (selectedDate) { 1291 if ( $(this).attr('name') === 'filter_with_start_date' ) { 1292 $endDate.datepicker('option', 'minDate', selectedDate); 1293 $endDate.trigger('change'); 1294 } else if ( $(this).attr('name') === 'filter_with_end_date' ) { 1295 $startDate.datepicker('option', 'maxDate', selectedDate); 1296 $startDate.trigger('change'); 1297 } 1298 //applyAllFilters(); 1299 } 1300 }); 1301 } 1302 initDatepicker($startDate); 1303 initDatepicker($endDate); 1304 panel.data('datepicker-init', true); 1305 } 1306 }); 1307}(jQuery)); 1308(function ($) { 1309 "use strict"; 1310 //*****************************Faq***********************************// 1311 $(document).on('click', '.mep-event-faq-set > a', function () { 1312 let current = $(this); 1313 if (current.hasClass("active")) { 1314 current.removeClass("active"); 1315 current.siblings(".mep-event-faq-content").slideUp(200); 1316 $(".mep-event-faq-set > a i").removeClass("fa-minus").addClass("fa-plus"); 1317 } else { 1318 $(".mep-event-faq-set > a i").removeClass("fa-minus").addClass("fa-plus"); 1319 current.find("i").removeClass("fa-plus").addClass("fa-minus"); 1320 $(".mep-event-faq-set > a").removeClass("active"); 1321 current.addClass("active"); 1322 $(".mep-event-faq-content").slideUp(200); 1323 current.siblings(".mep-event-faq-content").slideDown(200); 1324 } 1325 }); 1326}(jQuery)); 1327(function ($) { 1328 $(document).on('click', 'button.mep_view_vr_btn', function () { 1329 $(this).closest('tr').next('tr.mep_virtual_event_info_sec').slideToggle('fast'); 1330 }); 1331 $(document).on('click', '.faq_items [data-collapse-target]', function () { 1332 $(this).find('i').toggleClass('fa-chevron-right fa-chevron-down'); 1333 }); 1334}(jQuery)); 1335/******************** Remove below function after 2025**********************/ 1336(function ($) { 1337 "use strict"; 1338 $(document).on('click', '.mep-event-list-loop .mp_event_visible_event_time', function (e) { 1339 e.preventDefault(); 1340 let target = $(this); 1341 $('.mep-event-list-loop .mp_event_visible_event_time').each(function () { 1342 let current = $(this).siblings('ul.mp_event_more_date_list'); 1343 if (current.is(':visible')) { 1344 let active_text = $(this).data('active-text'); 1345 $(this).html(active_text); 1346 current.slideUp(200); 1347 } 1348 }).promise().done(function () { 1349 let current_list = target.siblings('ul.mp_event_more_date_list'); 1350 if (current_list.length > 0) { 1351 if (current_list.is(':visible')) { 1352 current_list.slideUp(200); 1353 target.html(target.data('active-text')); 1354 } else { 1355 current_list.slideDown(200); 1356 target.html(target.data('hide-text')); 1357 } 1358 } else { 1359 let event_id = target.data('event-id'); 1360 $.ajax({ 1361 type: 'POST', 1362 url: mpwem_ajax_url, 1363 data: {"action": "mep_event_list_date_schedule", "event_id": event_id}, 1364 beforeSend: function () { 1365 target.html('<span class="fas fa-spinner fa-pulse"></span>'); 1366 }, 1367 success: function (data) { 1368 $(data).insertAfter(target); 1369 target.html(target.data('hide-text')); 1370 } 1371 }); 1372 } 1373 }); 1374 }); 1375}(jQuery)); 1376 1377 1378function showLoader() { 1379 const loader = document.getElementById('loader-overlay'); 1380 loader.classList.add('active'); 1381} 1382 1383function hideLoader() { 1384 const loader = document.getElementById('loader-overlay'); 1385 loader.classList.remove('active'); 1386} 1387// DatePicker Function 1388jQuery(document).ready(function ($) { 1389 1390 if (typeof mpwemDateData === 'undefined') { 1391 return; 1392 } 1393 1394 let selector = mpwemDateData.selector; 1395 let availableDates = mpwemDateData.availableDates; 1396 let minDateData = mpwemDateData.minDate; 1397 let maxDateData = mpwemDateData.maxDate; 1398 1399 $(selector).datepicker({ 1400 1401 dateFormat: mpwem_date_format, 1402 1403 minDate: new window.Date( 1404 minDateData.year, 1405 minDateData.month, 1406 minDateData.day 1407 ), 1408 1409 maxDate: new window.Date( 1410 maxDateData.year, 1411 maxDateData.month, 1412 maxDateData.day 1413 ), 1414 1415 autoSize: true, 1416 changeMonth: true, 1417 changeYear: true, 1418 1419 beforeShowDay: function (date) { 1420 1421 let d = date.getDate(); 1422 let m = date.getMonth() + 1; 1423 let y = date.getFullYear(); 1424 1425 let dmy = d + "-" + m + "-" + y; 1426 1427 if ($.inArray(dmy, availableDates) !== -1) { 1428 return [true, "", "Available"]; 1429 } 1430 1431 return [false, "", "Unavailable"]; 1432 }, 1433 onSelect: function (dateText, data) { 1434 1435 let date = data.selectedYear + '-' + 1436 ('0' + (parseInt(data.selectedMonth) + 1)).slice(-2) + '-' + 1437 ('0' + parseInt(data.selectedDay)).slice(-2); 1438 1439 $(this) 1440 .closest('label') 1441 .find('input[type="hidden"]') 1442 .val(date) 1443 .trigger('change'); 1444 } 1445 1446 }); 1447 1448}); 1449 1450 1451document.querySelectorAll('li').forEach(function(li) { 1452 // à¦à§à¦ à¦à¦°à§à¦¨ à¦à¦ li তৠprice à¦à¦à§ à¦à¦¿à¦¨à¦¾ 1453 if (li.querySelector('.woocommerce-Price-amount')) { 1454 let strong = li.querySelector('.wc-item-meta-label'); 1455 1456 if (strong) { 1457 // strong element à¦à¦° à¦à¦¿à¦¤à¦°à§à¦° সব child nodes à¦à§à¦ à¦à¦°à§à¦¨
1458 strong.childNodes.forEach(function(node) { 1459 // à¦à§à¦ à¦à¦°à§à¦¨ à¦à¦à¦¿ text node à¦à¦¿à¦¨à¦¾ 1460 if (node.nodeType === Node.TEXT_NODE) { 1461 // সব text node থà§à¦à§ : à¦à¦¬à¦ - রিমà§à¦ à¦à¦°à§ সà§à¦ªà§à¦¸ দিন 1462 node.textContent = node.textContent.replace(/[:-]/g, ' '); 1463 1464 // ঠতিরিà¦à§à¦¤ সà§à¦ªà§à¦¸ à¦à¦®à¦¾à¦¤à§ à¦à¦¾à¦à¦²à§ (optional) 1465 //node.textContent = node.textContent.replace(/\s+/g, ' ').trim(); 1466 } 1467 }); 1468 } 1469 } 1470}); 1471 1472 1473(function ($) { 1474 "use strict"; 1475 $(document).on('submit', '#mpwem_registration', function(e) { 1476 if ($(this).find('.mep-rsvp-submit-btn').length === 0) { 1477 return; 1478 } 1479 e.preventDefault(); 1480 const $form = $(this); 1481 const $btn = $form.find('.mep-rsvp-submit-btn'); 1482 const $msg = $form.find('.mep-rsvp-message'); 1483 1484 $btn.prop('disabled', true).find('span').text('Submitting...'); 1485 $msg.hide().removeClass('success error'); 1486 1487 $.ajax({ 1488 url: mpwem_script_var ? mpwem_script_var.url : mpwem_ajax_url, 1489 type: 'POST', 1490 data: $form.serialize(), 1491 success: function(response) { 1492 if (response.success) { 1493 $msg.text(response.data.message).addClass('success').show(); 1494 $form.find('input[type="text"], input[type="email"]').val(''); 1495 $form.find('input[type="number"]').val(1); 1496 } else { 1497 const errorMsg = response.data && response.data.message ? response.data.message : 'An error occurred. Please try again.'; 1498 $msg.text(errorMsg).addClass('error').show(); 1499 } 1500 }, 1501 error: function() { 1502 $msg.text('Connection error. Please try again.').addClass('error').show(); 1503 }, 1504 complete: function() { 1505 $btn.prop('disabled', false).find('span').text('Submit RSVP'); 1506 } 1507 }); 1508 }); 1509}(jQuery)); 1510 1511/* ============================================================ 1512 * Enquiry ("query") form â Announcement-mode events. 1513 * Posts to wp_ajax_mep_submit_enquiry (MPWEM_Hooks::mep_submit_enquiry). 1514 * Deliberately its own <form>, so it never collides with the RSVP handler 1515 * bound to #mpwem_registration above. 1516 * ============================================================ */ 1517(function ($) { 1518 "use strict"; 1519 $(document).on('submit', '.mpwem_enquiry_form', function (e) { 1520 e.preventDefault(); 1521 1522 var $form = $(this); 1523 if ($form.data('mpwemEnquirySubmitting')) { 1524 return; 1525 } 1526 1527 var $btn = $form.find('.mpwem_enquiry_submit_btn'); 1528 var $label = $btn.find('span'); 1529 var $msg = $form.find('.mpwem_enquiry_message'); 1530 var originalLabel = $label.text(); 1531 1532 // Let the browser surface its own messages for required/typed fields first. 1533 if (this.checkValidity && !this.checkValidity()) { 1534 this.reportValidity && this.reportValidity(); 1535 return; 1536 } 1537 1538 $form.data('mpwemEnquirySubmitting', true); 1539 $btn.prop('disabled', true); 1540 $label.text($btn.data('sending-text') || 'Sending...'); 1541 $msg.hide().removeClass('success error').text(''); 1542 1543 $.ajax({ 1544 url: (typeof mpwem_script_var !== 'undefined' && mpwem_script_var.url) ? mpwem_script_var.url : (typeof mpwem_ajax_url !== 'undefined' ? mpwem_ajax_url : ''), 1545 type: 'POST', 1546 data: $form.serialize(), 1547 success: function (response) { 1548 if (response && response.success) { 1549 $msg.text(response.data.message).addClass('success').show(); 1550 $form.find('input[type="text"], input[type="email"], textarea').val(''); 1551 } else { 1552 var errorMsg = (response && response.data && response.data.message) 1553 ? response.data.message 1554 : 'An error occurred. Please try again.'; 1555 $msg.text(errorMsg).addClass('error').show(); 1556 } 1557 }, 1558 error: function () { 1559 $msg.text('Connection error. Please try again.').addClass('error').show(); 1560 }, 1561 complete: function () { 1562 $form.data('mpwemEnquirySubmitting', false); 1563 $btn.prop('disabled', false);
1564 $label.text(originalLabel); 1565 } 1566 }); 1567 }); 1568}(jQuery)); 1569 1570/* ============================================================ 1571 * Native Checkout â runs when WooCommerce is not active. 1572 * Intercepts mpwem_book_now clicks and shows the billing modal. 1573 * ============================================================ */ 1574(function ($) { 1575 'use strict'; 1576 1577 // sessionStorage key prefix used to persist a booking intent across a login redirect. 1578 var PENDING_BOOKING_PREFIX = 'mep_pending_booking_'; 1579 1580 // Helper: resolve the selected occurrence's full date AND time for native checkout. 1581 // The hidden mep_event_start_date field can collapse to a date-only value (saved as 1582 // "Y-m-d 00:00") for recurring events that have several times per day, which loses the 1583 // chosen time slot. The date/time selectors always carry the full datetime, so prefer 1584 // them: mpwem_time (date + time-slot) > mpwem_date_time (occurrence) > mep_event_start_date. 1585 // This is native-only and deliberately does not touch the shared $user_date logic used 1586 // by the WooCommerce flow. 1587 function mepResolveEventDate(parent) { 1588 var candidates = [ 1589 parent.find('[name="mpwem_time"]').val(), 1590 parent.find('[name="mpwem_date_time"]').val(), 1591 parent.find('[name="mep_event_start_date[]"]').first().val() 1592 ]; 1593 // Prefer the first candidate that includes a time component. 1594 for (var i = 0; i < candidates.length; i++) { 1595 var v = $.trim(candidates[i] || ''); 1596 if (v && v.indexOf(':') !== -1) { return v; } 1597 } 1598 // No time component anywhere (genuinely date-only event) â use the first value present. 1599 for (var j = 0; j < candidates.length; j++) { 1600 var v2 = $.trim(candidates[j] || ''); 1601 if (v2) { return v2; } 1602 } 1603 return ''; 1604 } 1605 1606 // Helper: HTML-escape a string for safe insertion into the summary markup. 1607 function mepNativeEsc(str) { 1608 return $('<span>').text(str == null ? '' : String(str)).html(); 1609 } 1610 1611 // Helper: present the resolved event datetime, dropping a meaningless midnight time 1612 // (e.g. "2026-07-22 00:00" â "2026-07-22") so only real times are shown. 1613 function mepNativeFormatEventDate(raw) { 1614 raw = $.trim(raw || ''); 1615 if (!raw) { return ''; } 1616 return raw.replace(/\s+00:00(:00)?$/, ''); 1617 } 1618 1619 // Helper: collect ticket data from the registration form 1620 function mepCollectTickets(parent) { 1621 var tickets = []; 1622 parent.find('[name="option_qty[]"]').each(function () { 1623 var qty = parseInt($(this).val()) || 0; 1624 if (qty <= 0) return; 1625 var price = parseFloat($(this).attr('data-price')) || 0; 1626 var $item = $(this).closest('.mep_ticket_item, .mpwem_ticket_row'); 1627 var name = $item.find('[name="option_name[]"]').val() 1628 || $item.find('[name="ticket_type[]"]').val() 1629 || 'Ticket'; 1630 tickets.push({ ticket_name: name, ticket_qty: qty, ticket_price: price }); 1631 }); 1632 return tickets; 1633 } 1634 1635 // Helper: collect form-builder attendee fields (rendered as name="field[]") into a plain object 1636 function mepCollectAttendeeFields(parent) { 1637 var fields = {}; 1638 parent.find('.mep_attendee_info [name$="[]"], .mep_attendee_info_hidden [name$="[]"]').each(function () { 1639 var $field = $(this); 1640 if ($field.attr('type') === 'file') { 1641 return; 1642 } 1643 var name = ($field.attr('name') || '').replace(/\[\]$/, ''); 1644 if (name) { 1645 fields[name] = $field.val(); 1646 } 1647 }); 1648 return fields; 1649 } 1650 1651 // Helper: restore previously-selected ticket quantities (used after a login redirect) 1652 function mepRestoreTickets(parent, tickets) { 1653 if (!Array.isArray(tickets)) { 1654 return; 1655 } 1656 tickets.forEach(function (t) { 1657 parent.find('[name="option_qty[]"]').each(function () { 1658 var $qty = $(this); 1659 var $item = $qty.closest('.mep_ticket_item, .mpwem_ticket_row'); 1660 var name = $item.find('[name="option_name[]"]').val() 1661 || $item.find('[name="ticket_type[]"]').val(); 1662 if (name === t.ticket_name) { 1663 $qty.val(t.ticket_qty).trigger('change'); 1664 } 1665 }); 1666 }); 1667 } 1668 1669 // Helper: restore previously-entered attendee form fields (used after a login redirect) 1670 function mepRestoreAttendeeFields(parent, fields) { 1671 if (!fields) { 1672 return; 1673 }
1674 Object.keys(fields).forEach(function (name) { 1675 parent.find('.mep_attendee_info [name="' + name + '[]"], .mep_attendee_info_hidden [name="' + name + '[]"]') 1676 .val(fields[name]); 1677 }); 1678 } 1679 1680 // Helper: format a number as currency using the JS constants set by php 1681 function mepNativeFormatPrice(amount) { 1682 if (typeof mpwem_price_format === 'function') { 1683 return mpwem_price_format(amount); 1684 } 1685 var symbol = (typeof mpwem_currency_symbol !== 'undefined') ? mpwem_currency_symbol : '$'; 1686 var position = (typeof mpwem_currency_position !== 'undefined') ? mpwem_currency_position : 'left'; 1687 var decimals = (typeof mpwem_num_of_decimal !== 'undefined') ? parseInt(mpwem_num_of_decimal) : 2; 1688 var fixed = parseFloat(amount).toFixed(decimals); 1689 switch (position) { 1690 case 'right': return fixed + symbol; 1691 case 'left_space': return symbol + ' ' + fixed; 1692 case 'right_space': return fixed + ' ' + symbol; 1693 default: return symbol + fixed; 1694 } 1695 } 1696 1697 // Open the native checkout modal, pre-populated with ticket summary 1698 function mepOpenNativeModal(parent) { 1699 var tickets = mepCollectTickets(parent); 1700 if (!tickets.length) { 1701 alert('Please Select Ticket Type'); 1702 return; 1703 } 1704 1705 var total = 0; 1706 var summaryHtml = ''; 1707 tickets.forEach(function (t) { 1708 var lineTotal = t.ticket_price * t.ticket_qty; 1709 total += lineTotal; 1710 summaryHtml += '<div class="mep-ticket-summary-row">' 1711 + '<div class="mep-tsr-info">' 1712 + '<span class="mep-tsr-name">' + mepNativeEsc(t.ticket_name) + '</span>' 1713 + '<span class="mep-tsr-sub">' + mepNativeEsc(String(t.ticket_qty)) + ' × ' + mepNativeFormatPrice(t.ticket_price) + '</span>' 1714 + '</div>' 1715 + '<span class="mep-tsr-total">' + mepNativeFormatPrice(lineTotal) + '</span>' 1716 + '</div>'; 1717 }); 1718 1719 var $modal = $('#mep-native-checkout-modal'); 1720 var eventDate = mepResolveEventDate(parent); 1721 1722 $modal.find('#mep-native-ticket-summary').html(summaryHtml); 1723 $modal.find('#mep-native-total-display').text(mepNativeFormatPrice(total)); 1724 1725 // Event datetime line (hide the time when it's a meaningless midnight value). 1726 var dtText = mepNativeFormatEventDate(eventDate); 1727 var $dt = $modal.find('#mep-native-event-datetime'); 1728 if (dtText) { $dt.text(dtText).show(); } else { $dt.text('').hide(); } 1729 $modal.find('#mep-native-ticket-data').val(JSON.stringify(tickets)); 1730 $modal.find('#mep-native-event-date').val(eventDate); 1731 $modal.find('#mep-native-checkout-msg').hide().removeClass('success error').text(''); 1732 1733 // Collect attendee field values from the main registration form so they are 1734 // saved with the order even though the fields are not shown inside this modal. 1735 // Only take the first occurrence of each field name (handles multi-ticket layouts 1736 // where the same attendee form is cloned once per ticket row). 1737 // Collect the registration-form fields once per seat, mirroring the WooCommerce 1738 // flow: each field posts as an array indexed by the global seat order and the server 1739 // builds one attendee per seat from it. Only the visible per-seat forms 1740 // (.mep_attendee_info) are read â never the hidden clone template. 1741 var attendeeFieldArrays = {}; // field name -> [value per seat] (submitted to the server) 1742 var fieldOrder = []; // field names, in display order 1743 var fieldLabels = {}; // field name -> human label 1744 var fieldTypes = {}; // field name -> input type 1745 parent.find('.mep_attendee_info [data-field-name][data-d-name]').each(function () { 1746 var $inp = $(this); 1747 var fname = $inp.data('field-name'); 1748 var type = ($inp.attr('type') || '').toLowerCase(); 1749 if (!fname || type === 'file') { 1750 return;
1750 // file uploads are not supported in native checkout 1751 } 1752 (attendeeFieldArrays[fname] = attendeeFieldArrays[fname] || []).push($.trim($inp.val())); 1753 if (!fieldLabels.hasOwnProperty(fname)) { 1754 fieldOrder.push(fname); 1755 fieldTypes[fname] = type; 1756 fieldLabels[fname] = $.trim($inp.closest('.mp_form_item').find('label span').first().text().replace(/\*+\s*$/, '')) 1757 || $.trim($inp.attr('placeholder') || '') 1758 || fname; 1759 } 1760 }); 1761 $modal.find('#mep-native-attendee-snapshot').val(JSON.stringify(attendeeFieldArrays)); 1762 1763 // Build a compact, per-attendee preview of the registration details. 1764 var seatCount = 0; 1765 fieldOrder.forEach(function (f) { seatCount = Math.max(seatCount, attendeeFieldArrays[f].length); }); 1766 var detailsHtml = ''; 1767 for (var s = 0; s < seatCount; s++) { 1768 var rows = ''; 1769 fieldOrder.forEach(function (fname) { 1770 if (fieldTypes[fname] === 'hidden') { return; } 1771 var v = attendeeFieldArrays[fname][s]; 1772 v = (v == null) ? '' : $.trim(v); 1773 if (!v) { return; } 1774 rows += '<div class="mep-native-detail-row">' 1775 + '<span class="mep-ndr-label">' + mepNativeEsc(fieldLabels[fname]) + '</span>' 1776 + '<span class="mep-ndr-value">' + mepNativeEsc(v) + '</span>' 1777 + '</div>'; 1778 }); 1779 if (rows) { 1780 var heading = seatCount > 1 ? ('Attendee ' + (s + 1)) : 'Registration Details'; 1781 detailsHtml += '<div class="mep-native-attendee-block">' 1782 + '<div class="mep-native-detail-title">' + mepNativeEsc(heading) + '</div>' 1783 + rows + '</div>'; 1784 } 1785 } 1786 1787 var $details = $modal.find('#mep-native-attendee-details'); 1788 if (detailsHtml) { 1789 $details.html(detailsHtml).show(); 1790 } else { 1791 $details.empty().hide(); 1792 } 1793 1794 // Prefill the billing form from the event's attendee name/email/phone fields 1795 // (when present) so the user doesn't retype them. 1796 var preBilling = { name: '', email: '', phone: '' }; 1797 parent.find('[data-field-name][data-d-name]').each(function () { 1798 var dname = $(this).data('d-name'); 1799 var val = $.trim($(this).val()); 1800 if (!val) { return; } 1801 if (dname === 'ea_name' && !preBilling.name) { preBilling.name = val; } 1802 if (dname === 'ea_email' && !preBilling.email) { preBilling.email = val; } 1803 if (dname === 'ea_phone' && !preBilling.phone) { preBilling.phone = val; } 1804 }); 1805 if (preBilling.name) { $modal.find('#mep-native-billing-name').val(preBilling.name); } 1806 if (preBilling.email) { $modal.find('#mep-native-billing-email').val(preBilling.email); } 1807 if (preBilling.phone) { $modal.find('#mep-native-billing-phone').val(preBilling.phone); } 1808 1809 // When login is required to complete checkout, persist the ticket selection so it can 1810 // be restored once the user logs in and is redirected back to this page. 1811 if ($modal.find('.mep-native-login-required').length && window.sessionStorage) { 1812 var eventId = $modal.find('#mep-native-event-id').val(); 1813 if (eventId) { 1814 try { 1815 sessionStorage.setItem(PENDING_BOOKING_PREFIX + eventId, JSON.stringify({ 1816 tickets: tickets, 1817 eventDate: eventDate 1818 })); 1819 } catch (e) {} 1820 } 1821 } 1822 1823 $modal.css('display', 'flex').hide().fadeIn(200); 1824 } 1825 1826 // Intercept book-now when native mode is present 1827 $(document).on('click', '.mpwem_book_now', function () { 1828 var parent = $(this).closest('.mpwem_registration_area'); 1829 if (!parent.find('.mpwem_native_checkout_trigger').length) { 1830 return; // WooCommerce mode â let the existing handlers work 1831 } 1832 var totalQty = 0; 1833 parent.find('[name="option_qty[]"]').each(function () { 1834 totalQty += parseInt($(this).val()) || 0; 1835 }); 1836 if (totalQty <= 0) { 1837 parent.find('[name="option_qty[]"]').addClass('error'); 1838 return; 1839 } 1840 parent.find('[name="option_qty[]"]').removeClass('error'); 1841 mepOpenNativeModal(parent); 1842 }); 1843 1844 // Close modal 1845 $(document).on('click', '.mep-native-modal-close', function () { 1846 $('#mep-native-checkout-modal').fadeOut(200); 1847 }); 1848 $(document).on('click', '#mep-native-checkout-modal', function (e) { 1849 if ($(e.target).is('#mep-native-checkout-modal')) { 1850 $(this).fadeOut(200); 1851 } 1852 }); 1853 $(document).on('keydown', function (e) { 1854 if (e.key === 'Escape') { 1855 $('#mep-native-checkout-modal').fadeOut(200); 1856 } 1857 }); 1858 1859 // Submit native checkout 1860 $(document).on('click', '#mep-native-confirm-btn', function () { 1861 var $btn = $(this); 1862 var $modal = $('#mep-native-checkout-modal'); 1863 var $msg = $modal.find('#mep-native-checkout-msg'); 1864 var eventId = $modal.find('#mep-native-event-id').val(); 1865 var nonce = $modal.find('#mep-native-nonce').val(); 1866 var ticketData = $modal.find('#mep-native-ticket-data').val(); 1867 var eventDate = $modal.find('#mep-native-event-date').val(); 1868 var payMethod = $modal.find('[name="mep_payment_method"]:checked').val() || 'offline'; 1869 1870 $msg.hide().removeClass('success error').text(''); 1871 1872 // Read the attendee field snapshot collected from the main form when the modal opened. 1873 var attendeeFields = {}; 1874 var billingName = ''; 1875 var billingEmail = ''; 1876 var billingPhone = ''; 1877 try { 1878 var snapshotRaw = $modal.find('#mep-native-attendee-snapsh
1878ot').val(); 1879 if (snapshotRaw) { 1880 attendeeFields = JSON.parse(snapshotRaw) || {}; 1881 } 1882 } catch (e) {} 1883 1884 // Read billing details from the modal's billing form (all fields required). 1885 var $bName = $modal.find('#mep-native-billing-name'); 1886 if ($bName.length) { 1887 var $bEmail = $modal.find('#mep-native-billing-email'); 1888 var $bPhone = $modal.find('#mep-native-billing-phone'); 1889 billingName = $.trim($bName.val() || ''); 1890 billingEmail = $.trim($bEmail.val() || ''); 1891 billingPhone = $.trim($bPhone.val() || ''); 1892 1893 $modal.find('.mep-native-input').removeClass('mep-native-input-error'); 1894 var missing = []; 1895 if (!billingName) { missing.push($bName); } 1896 if (!billingEmail) { missing.push($bEmail); } 1897 if (!billingPhone) { missing.push($bPhone); } 1898 if (missing.length) { 1899 missing.forEach(function ($f) { $f.addClass('mep-native-input-error'); }); 1900 $msg.text('Please fill in all billing details (name, email and phone).').addClass('error').show(); 1901 return; 1902 } 1903 } else { 1904 // Fallback (older template): derive billing from the first attendee's fields. 1905 $('.mpwem_registration_area').find('.mep_attendee_info [data-field-name][data-d-name]').each(function () { 1906 var $inp = $(this); 1907 var fname = $inp.data('field-name'); 1908 var dname = $inp.data('d-name'); 1909 var v = attendeeFields[fname]; 1910 if (Array.isArray(v)) { v = v[0]; } 1911 if (v === undefined) { return; } 1912 if (dname === 'ea_name' && !billingName) billingName = v; 1913 if (dname === 'ea_email' && !billingEmail) billingEmail = v; 1914 if (dname === 'ea_phone' && !billingPhone) billingPhone = v; 1915 }); 1916 } 1917 1918 if (billingEmail && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(billingEmail)) { 1919 $modal.find('#mep-native-billing-email').addClass('mep-native-input-error'); 1920 $msg.text('Please enter a valid email address.').addClass('error').show(); 1921 return; 1922 } 1923 1924 $btn.prop('disabled', true) 1925 .find('.mep-native-btn-text').hide().end() 1926 .find('.mep-native-btn-loading').show(); 1927 1928 var ajaxUrl = (typeof mpwem_script_var !== 'undefined' && mpwem_script_var.url) 1929 ? mpwem_script_var.url 1930 : (typeof mpwem_ajax_url !== 'undefined' ? mpwem_ajax_url : '/wp-admin/admin-ajax.php'); 1931 1932 $.ajax({ 1933 url: ajaxUrl, 1934 type: 'POST', 1935 data: { 1936 action: 'mep_native_checkout', 1937 nonce: nonce, 1938 event_id: eventId, 1939 billing_name: billingName, 1940 billing_email: billingEmail, 1941 billing_phone: billingPhone, 1942 event_date: eventDate, 1943 ticket_data: ticketData, 1944 attendee_fields: JSON.stringify(attendeeFields), 1945 payment_method: payMethod 1946 }, 1947 success: function (response) { 1948 if (response.success) { 1949 // Booking succeeded â clear any persisted intent for this event. 1950 if (window.sessionStorage) { 1951 try { sessionStorage.removeItem(PENDING_BOOKING_PREFIX + eventId); } catch (e) {} 1952 } 1953 $msg.text(response.data.message).addClass('success').show(); 1954 // Gateway redirect (PayPal, Stripe) â go immediately, no delay 1955 if (response.data.requires_redirect && response.data.redirect) { 1956 window.location.href = response.data.redirect; 1957 } else { 1958 // Free / offline â show success message then redirect to confirmation page 1959 setTimeout(function () { 1960 if (response.data.redirect) { 1961 window.location.href = response.data.redirect; 1962 } else { 1963 $modal.fadeOut(300); 1964 } 1965 }, 1800); 1966 } 1967 } else { 1968 var errMsg = (response.data && response.data.message) 1969 ? response.data.message 1970 : 'An error occurred. Please try again.'; 1971 $msg.text(errMsg).addClass('error').show(); 1972 $btn.prop('disabled', false) 1973 .find('.mep-native-btn-text').show().end() 1974 .find('.mep-native-btn-loading').hide(); 1975 } 1976 }, 1977 error: function () { 1978 $msg.text('Connection error. Please try again.').addClass('error').show(); 1979 $btn.prop('disabled', false) 1980 .find('.mep-native-btn-text').show().end() 1981 .find('.mep-native-btn-loading').hide(); 1982 } 1983 }); 1984 }); 1985 1986 // Restore a booking intent persisted before a login redirect, then reopen the modal. 1987 $(function () { 1988 if (typeof mpwem_script_var === 'undefined' || mpwem_script_var.is_logged_in !== '1' || !window.sessionStorage) { 1989 return; 1990 } 1991 $('.mpwem_registration_area').each(function () { 1992 var $area = $(this); 1993 var eventId = $area.find('#mep-native-event-id').val(); 1994 if (!eventId) { 1995 return; 1996 } 1997 var raw = sessionStorage.getItem(PENDING_BOOKING_PREFIX + eventId); 1998 if (!raw) { 1999 return; 2000 } 2001 sessionStorage.removeItem(PENDING_BOOKING_PREFIX + eventId); 2002 var pending; 2003 try { 2004 pending = JSON.parse(raw); 2005 } catch (e) { 2006 return; 2007 }
2008 mepRestoreTickets($area, pending.tickets); 2009 mepRestoreAttendeeFields($area, pending.attendeeFields); 2010 mepOpenNativeModal($area); 2011 }); 2012 }); 2013 2014}(jQuery)); 2015 2016//*****************************Description Read More***********************************// 2017(function ($) { 2018 "use strict"; 2019 2020 function mpwemCountWords(text) { 2021 var trimmed = (text || '').replace(/\s+/g, ' ').trim(); 2022 if (!trimmed) { 2023 return 0; 2024 } 2025 return trimmed.split(' ').length; 2026 } 2027 2028 function mpwemGetDescriptionOverflow(content, limit) { 2029 var count = 0; 2030 var reached = false; 2031 var overflow = []; 2032 2033 $(content).contents().each(function () { 2034 if (reached) { 2035 if (this.nodeType === 1) { 2036 overflow.push(this); 2037 } 2038 return; 2039 } 2040 2041 count += mpwemCountWords(this.textContent || ''); 2042 if (count >= limit) { 2043 reached = true; 2044 } 2045 }); 2046 2047 return overflow; 2048 } 2049 2050 function mpwemInitDetailsReadMore() { 2051 $('.mpwem_details--has-readmore').each(function () { 2052 var $wrap = $(this); 2053 if ($wrap.data('readmore-ready')) { 2054 return; 2055 } 2056 2057 var $content = $wrap.find('.mpwem_details_content').first(); 2058 var $button = $wrap.find('.mpwem_details_readmore').first(); 2059 if (!$content.length || !$button.length) { 2060 return; 2061 } 2062 2063 var limit = parseInt($wrap.attr('data-readmore-words'), 10) || 200; 2064 var wordCount = mpwemCountWords($content.text()); 2065 2066 if (wordCount <= limit) { 2067 $content.removeClass('is-collapsed'); 2068 $button.remove(); 2069 $wrap.removeClass('mpwem_details--has-readmore'); 2070 $wrap.data('readmore-ready', true); 2071 return; 2072 } 2073 2074 var overflow = mpwemGetDescriptionOverflow($content.get(0), limit); 2075 if (!overflow.length) { 2076 $button.remove(); 2077 $wrap.removeClass('mpwem_details--has-readmore'); 2078 $wrap.data('readmore-ready', true); 2079 return; 2080 } 2081 2082 $(overflow).addClass('mpwem_details_readmore__overflow'); 2083 $content.addClass('is-collapsed'); 2084 $wrap.addClass('is-collapsed').data('readmore-ready', true); 2085 }); 2086 } 2087 2088 function mpwemInitSpeakerRoleReadMore() { 2089 $(document).on('click', '[data-mep-speaker-role-toggle]', function (e) { 2090 e.preventDefault(); 2091 e.stopPropagation(); 2092 2093 var $button = $(this); 2094 var $wrap = $button.closest('[data-mep-speaker-role]'); 2095 var $text = $wrap.find('.mep-default-speaker__role-text').first(); 2096 if (!$wrap.length || !$text.length) { 2097 return; 2098 } 2099 2100 var expanded = $wrap.hasClass('is-expanded'); 2101 var shortText = $text.attr('data-short') || ''; 2102 var fullText = $text.attr('data-full') || ''; 2103 2104 if (expanded) { 2105 $text.text(shortText + 'â¦'); 2106 $wrap.removeClass('is-expanded').addClass('is-collapsed'); 2107 $button.attr('aria-expanded', 'false'); 2108 } else { 2109 $text.text(fullText); 2110 $wrap.addClass('is-expanded').removeClass('is-collapsed'); 2111 $button.attr('aria-expanded', 'true'); 2112 } 2113 }); 2114 } 2115 2116 $(document).ready(function () { 2117 mpwemInitDetailsReadMore(); 2118 mpwemInitSpeakerRoleReadMore(); 2119 }); 2120 2121 $(document).on('click', '.mpwem_details_readmore', function (e) { 2122 e.preventDefault(); 2123 var $button = $(this); 2124 var $wrap = $button.closest('.mpwem_details--has-readmore'); 2125 var $content = $wrap.find('.mpwem_details_content').first(); 2126 if (!$wrap.length || !$content.length) { 2127 return; 2128 } 2129 2130 var expanded = $wrap.hasClass('is-expanded'); 2131 if (expanded) { 2132 $content.addClass('is-collapsed'); 2133 $wrap.removeClass('is-expanded').addClass('is-collapsed'); 2134 $button.attr('aria-expanded', 'false'); 2135 } else { 2136 $content.removeClass('is-collapsed'); 2137 $wrap.addClass('is-expanded').removeClass('is-collapsed'); 2138 $button.attr('aria-expanded', 'true'); 2139 } 2140 }); 2141}(jQuery));
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.