1(function($) { 2 $(document).ready(function() { 3 // Handle form labels 4 const $placeholderInputs = $('.mp-form-row .mepr-form-input'); 5 6 $.each($placeholderInputs, function(index, input) { 7 const $label = $(this).siblings('.mp-form-label').find('label'); 8 9 if($(this).val() !== '' || $(this).is('select')) { 10 $label.addClass('active'); 11 } else { 12 $label.removeClass('active'); 13 } 14 15 $(input).on('keyup', function(event) { 16 if($(this).val() !== '') { 17 $label.addClass('active'); 18 } else { 19 $label.removeClass('active'); 20 } 21 }); 22 }); 23 24 $('body').on('click', '.mepr-signup-form .have-coupon-link', function(e) { 25 e.preventDefault(); 26 $(this).hide(); 27 $('div.mepr_coupon_'+$(this).data("prdid")).show(); 28 }); 29 30 $('body').on('keydown', '.mepr-signup-form .mepr-coupon-code', function(e) { 31 if(e.which === 13) { 32 e.preventDefault(); 33 $(this).trigger('blur'); 34 } 35 }); 36 37 // Store the default price string 38 $('.mepr_price_cell').each(function () { 39 $(this).data('default-price-string', $(this).text()); 40 }); 41 42 // All checkout-state bookkeeping is stored per form (as form data), so 43 // multiple signup forms on the same page update and settle independently. 44 // Key flags: `meprCheckoutStateUpdating` blocks submission until the state is 45 // reconciled, `meprUpdateCheckoutStatePending` marks that a newer update is 46 // scheduled but has not run yet, and `meprUpdatingCheckoutState` guards a 47 // single in-flight request. 48 const updateCheckoutState = function ($form) { 49 clearTimeout($form.data('meprUpdateCheckoutStateTimeout')); 50 51 // Block form submission until the checkout state is reconciled, and record 52 // that a newer update is scheduled so an earlier request's completion does 53 // not settle (and release a queued submit) before this update has run. 54 $form.data('meprCheckoutStateUpdating', true); 55 $form.data('meprUpdateCheckoutStatePending', true); 56 57 $form.data('meprUpdateCheckoutStateTimeout', setTimeout(function () { 58 debouncedUpdateCheckoutState($form); 59 }, 50)); 60 }; 61 62 const settleCheckoutStateUpdate = function ($form) { 63 // The completed request has finished its retry lifecycle, so clear the 64 // retry flag even when a newer update is still pending: the next scheduled 65 // update gets its own retry budget. 66 $form.removeData('meprUpdateCheckoutStateRetried'); 67 68 // A newer update is still scheduled; keep the submission blocked until it runs 69 // so the form settles against the latest checkout state, not an earlier one. 70 if ($form.data('meprUpdateCheckoutStatePending')) { 71 return; 72 } 73 74 $form.removeData('meprCheckoutStateUpdating'); 75 76 if ($form.data('meprSubmitWhenUpdated')) { 77 $form.removeData('meprSubmitWhenUpdated'); 78 79 // A disabled button would swallow the triggered click. 80 $form.find('.mepr-submit').prop('disabled', false).trigger('click'); 81 } 82 }; 83 84 const getRequestData = function ($form) { 85 let payment_methods = []; 86 87 $form.find('input[name="mepr_payment_method"]').each(function () { 88 payment_methods.push($(this).val()); 89 }); 90 91 const data = { 92 action: 'mepr_get_checkout_state', 93 mepr_product_id: $form.find('input[name="mepr_product_id"]').val(), 94 'mepr-address-one': $form.find('input[name="mepr-address-one"]').val(), 95 'mepr-address-two': $form.find('input[name="mepr-address-two"]').val(), 96 'mepr-address-city': $form.find('input[name="mepr-address-city"]').val(), 97 'mepr-address-state': $form.find('select[name="mepr-address-state"]').is(':visible') ? $form.find('select[name="mepr-address-state"]').val() : $form.find('input[name="mepr-address-state"]').val(), 98 'mepr-address-country': $form.find('select[name="mepr-address-country"]').val(), 99 'mepr-address-zip': $form.find('input[name="mepr-address-zip"]').val(), 100 mepr_vat_number: $form.find('input[name="mepr_vat_number"]').val(), 101 mepr_vat_customer_type: $form.find('input[name="mepr_vat_customer_type"]:checked').val(), 102 mepr_coupon_code: $form.find('input[name="mepr_coupon_code"]').val(), 103 mepr_coupon_nonce: MeprSignup.coupon_nonce, 104 mepr_is_product_page: (typeof MeprProTemplateSignup !== 'undefined' && MeprProTemplateSignup.is_product_page) || MeprSignup.is_product_page, 105 mpca_corporate_account_id: $form.find('input[name="mpca_corporate_account_id"]').val(), 106 mpgft_gift_checkbox: $form.find('input[name="mpgft-signup-gift-checkbox"]').is(':checked'), 107 mepr_payment_methods: payment_methods 108 }; 109 110 if (!data.mpgft_gift_checkbox) { 111 let order_bumps = []; 112 113 $form.find('input[name="mepr_order_bumps[]"]:checked').each(function () { 114 order_bumps.push($(this).val()); 115 }); 116 117 data.mepr_order_bumps = order_bumps; 118 } 119 120 $form.trigger('meprCheckoutStateRequestData', [data]); 121 122 return data; 123 }; 124 125 const debouncedUpdateCheckoutState = function ($form) { 126 // The scheduled update is now running, so it is no longer pending.
127 $form.removeData('meprUpdateCheckoutStatePending'); 128 129 // A request is already in flight. Defer via the "Again" flag; when that 130 // request completes it re-runs updateCheckoutState, which re-asserts the 131 // pending marker, so the submit lock is never dropped in the meantime. 132 if ($form.data('meprUpdatingCheckoutState')) { 133 $form.data('meprUpdateCheckoutStateAgain', true); 134 return; 135 } 136 137 const data = getRequestData($form); 138 139 if (JSON.stringify(data) === JSON.stringify($form.data('meprLastRequestData'))) { 140 settleCheckoutStateUpdate($form); 141 return; 142 } 143 144 $form.data('meprUpdatingCheckoutState', true); 145 $form.data('meprLastRequestData', data); 146 147 if (MeprSignup.spc_enabled === '1' && MeprSignup.spc_invoice === '1') { 148 $form.find('.mepr-invoice-loader').fadeIn(); 149 } 150 151 const onComplete = function () { 152 if (MeprSignup.spc_enabled === '1' && MeprSignup.spc_invoice === '1') { 153 $form.find('.mepr-invoice-loader').stop().hide(); 154 } 155 156 $form.removeData('meprUpdatingCheckoutState'); 157 }; 158 159 $.ajax({ 160 type: 'POST', 161 url: MeprI18n.ajaxurl, 162 dataType: 'json', 163 data: data 164 }) 165 .done(function (response) { 166 if (response && typeof response.success === 'boolean' && response.success) { 167 $form.trigger('meprPriceStringUpdated', [response.data]); 168 $form.find('div.mepr_price_cell').html(response.data.price_string); 169 170 if (response.data.payment_required) { 171 $form.find('.mepr-payment-methods-wrapper').show(); 172 $form.find('input[name="mepr_payment_methods_hidden"]').remove(); 173 } else { 174 $form.find('.mepr-payment-methods-wrapper').hide(); 175 $form.append('<input type="hidden" name="mepr_payment_methods_hidden" value="1">'); 176 177 // Clear validation errors on fields now hidden 178 $form.find('.mepr-payment-methods-wrapper .mepr-form-input').each(function () { 179 meprValidateInput(this); 180 }); 181 } 182 183 $form.trigger('meprAfterPriceStringUpdated', [response.data]); 184 185 if (MeprSignup.spc_enabled === '1' && MeprSignup.spc_invoice === '1') { 186 $form.find('.mepr-transaction-invoice-wrapper > div').replaceWith(response.data.invoice_html); 187 $form.find(".mepr-transaction-invoice-wrapper .mp_invoice").css({ opacity: 1 }); 188 } 189 190 $form.trigger('meprAfterCheckoutStateUpdated', [response.data]); 191 192 onComplete(); 193 194 if ($form.data('meprUpdateCheckoutStateAgain')) { 195 $form.removeData('meprUpdateCheckoutStateAgain'); 196 updateCheckoutState($form); 197 } else { 198 settleCheckoutStateUpdate($form); 199 } 200 } else { 201 onComplete(); 202 settleCheckoutStateUpdate($form); 203 } 204 }) 205 .fail(function () { 206 onComplete(); 207 208 // Retry a failed update once before releasing any queued submission, so 209 // a transient error does not let the submit proceed unreconciled. 210 if (!$form.data('meprUpdateCheckoutStateRetried')) { 211 $form.data('meprUpdateCheckoutStateRetried', true); 212 $form.removeData('meprLastRequestData'); 213 updateCheckoutState($form); 214 return; 215 } 216 217 settleCheckoutStateUpdate($form); 218 }); 219 }; 220 221 $('.mepr-signup-form').on('meprUpdateCheckoutState', function (e, force) { 222 // A forced update bypasses the identical-request check, for when the 223 // checkout state changed server-side without any form fields changing. 224 if (force) { 225 $(this).removeData('meprLastRequestData'); 226 } 227 228 updateCheckoutState($(this)); 229 }); 230 231 $('.mepr-signup-form').each(function () { 232 var $form = $(this); 233 234 if($form.find('input[name="mpgft-signup-gift-checkbox"]').is(':checked')) { 235 updateCheckoutState($form); 236 } 237 238 // Trigger checkout update if coupon code exists on page load (e.g., URL parameter), otherwise the invoice is cut out 239 if($form.find('input[name="mepr_coupon_code"]').val()) { 240 updateCheckoutState($form); 241 } 242 243 }); 244 245 var meprValidateInput = function (obj, submitting) { 246 $(obj).removeClass('invalid'); 247 248 var form = $(obj).closest('.mepr-signup-form'); 249 250 if ($(obj).attr('required') !== undefined) { 251 var notBlank = mpValidateFieldNotBlank($(obj)); 252 253 // Special handling for state field - not required for countries without states 254 if ($(obj).attr('name') === 'mepr-address-state') { 255 var selectedCountry = form.find('select[name="mepr-address-country"]').val(); 256 257 if (selectedCountry && MeprI18n.countries_without_states && 258 MeprI18n.countries_without_states.indexOf(selectedCountry) !== -1) { 259 // This country doesn't require states, so validation always passes 260 mpToggleFieldValidation($(obj), true); 261 return; 262 } 263 } 264 265 mpToggleFieldValidation($(obj), notBlank); 266 } 267 268 // Validate actual email only if it's not empty otherwise let the required/un-required logic hold 269 if ($(obj).attr('type')==='email' && $(obj).val().length > 0) {
270 var validEmail = mpValidateEmail($(obj).val()); 271 mpToggleFieldValidation($(obj), validEmail); 272 } 273 274 // Validate the URL by using the browser validation functions 275 if ($(obj).attr('type')==='url' && $(obj).val().length > 0) { 276 var validURL = mpValidateUrl($(obj).val()); 277 mpToggleFieldValidation($(obj), validURL); 278 } 279 280 if ($(obj).hasClass('mepr-password-confirm')) { 281 var confirmMatch = $(obj).val() === form.find('.mepr-password').val(); 282 mpToggleFieldValidation($(obj), confirmMatch); 283 } 284 285 if($(obj).hasClass('mepr-coupon-code') && !submitting) { 286 var price_string = form.find('div.mepr_price_cell'); 287 288 if($(obj).val().match(/(\s|\S)/)) { 289 $(obj).prev('.mp-form-label').find('.mepr-coupon-loader').fadeIn(); 290 $(obj).data('validating', true); 291 292 var data = { 293 action: 'mepr_validate_coupon', 294 code: $(obj).val(), 295 prd_id: $(obj).data("prdid"), 296 user_email: form.find("input[name='user_email']").val(), 297 coupon_nonce: MeprSignup.coupon_nonce 298 }; 299 300 $.post(MeprI18n.ajaxurl, data, function(res) { 301 $(obj).prev('.mp-form-label').find('.mepr-coupon-loader').hide(); 302 res = res.trim(); 303 mpToggleFieldValidation($(obj), (res.toString() == 'true')); 304 305 if(res.toString() == 'true') { 306 form.one('meprAfterPriceStringUpdated', function () { 307 $(obj).removeData('validating'); 308 309 if($(obj).data('submit-when-valid')) { 310 $(obj).removeData('submit-when-valid'); 311 form.find('.mepr-submit').trigger('click'); 312 } 313 }); 314 315 // Let's update price string and invoice 316 updateCheckoutState(form); 317 } 318 else { 319 form.find('.mepr-payment-methods-wrapper:hidden').show(); 320 form.find('input[name="mepr_payment_methods_hidden"]').remove(); 321 price_string.text(price_string.data('default-price-string')); 322 323 $(obj).removeData('validating'); 324 $(obj).removeData('submit-when-valid'); 325 326 // Invalid Coupon - update SPC Invoice 327 updateCheckoutState(form); 328 } 329 }) 330 .fail(function () { 331 // Also reached when the coupons feature is stripped and the 332 // mepr_validate_coupon endpoint no longer exists. 333 $(obj).prev('.mp-form-label').find('.mepr-coupon-loader').hide(); 334 mpToggleFieldValidation($(obj), false); 335 $(obj).removeData('validating'); 336 $(obj).removeData('submit-when-valid'); 337 }); 338 } 339 else if($(obj).val().trim() === '') { 340 if (form.find('.mepr-payment-methods-wrapper').is(':hidden')) { 341 // Looks like we need to restore the payment methods 342 form.find('.mepr-payment-methods-wrapper').show(); 343 form.find('input[name="mepr_payment_methods_hidden"]').remove(); 344 } 345 346 price_string.text(price_string.data('default-price-string')); 347 // Enpty Coupon - update SPC Invoice 348 updateCheckoutState(form); 349 } 350 } 351 352 $(obj).trigger('mepr-validate-input'); 353 }; 354 355 window.meprValidateInput = meprValidateInput; 356 357 $('body').on('focus', '.mepr-form .mepr-form-input', function (e) { 358 $(this).prev('.mp-form-label').find('.cc-error').hide(); 359 $(this).removeClass('invalid'); 360 }); 361 362 $('body').on('blur', '.mepr-form .mepr-form-input', function (e) { 363 //Don't validate date fields here, wait til the push the submit button 364 if(!$(this).hasClass('mepr-date-picker')) { 365 meprValidateInput(this); 366 } 367 }); 368 369 // Specific to validating with the datepicker ui text field 370 $('body').on('mepr-date-picker-closed', '.mepr-form .mepr-form-input.mepr-date-picker', function (e, date, inst) { 371 meprValidateInput(this); 372 }); 373 374 $('body').on('click', '.mepr-signup-form .mepr-submit', function (e) { 375 // We want to control if/when the form is submitted 376 e.preventDefault(); 377 378 var form = $(this).closest('.mepr-signup-form'); 379 var coupon = form.find('.mepr-coupon-code'); 380 381 if(coupon.data('validating')) { 382 coupon.data('submit-when-valid', true); 383 return; 384 } 385 386 // Wait for an in-flight checkout state update, so the payment fields are 387 // reconciled with the final order before the form is submitted. 388 if(form.data('meprCheckoutStateUpdating')) { 389 form.data('meprSubmitWhenUpdated', true); 390 return; 391 } 392 393 $.each(form.find('.mepr-form-input:visible'), function(i,obj) { 394 meprValidateInput(obj, true); 395 }); 396
397 if (0 < form.find('.invalid:visible').length) { 398 form.find('.validation').addClass('failed'); 399 } 400 else { 401 var submittedTelInputs = document.querySelectorAll(".mepr-tel-input"); 402 if (window.intlTelInputGlobals) { 403 for (var i = 0; i < submittedTelInputs.length; i++) { 404 var iti = window.intlTelInputGlobals.getInstance(submittedTelInputs[i]); 405 if (iti) { 406 submittedTelInputs[i].value = iti.getNumber(); 407 } 408 } 409 } 410 form.find('.validation').addClass('passed'); 411 this.disabled = true; 412 form.find('.mepr-loading-gif').show(); 413 $(this).trigger('mepr-register-submit'); 414 form.trigger('submit'); 415 } 416 }); 417 418 // A debounced window resize function, to fix a Square card input sizing issue. 419 const windowResize = (() => { 420 let timeoutId; 421 return () => { 422 clearTimeout(timeoutId); 423 timeoutId = setTimeout(() => { 424 window.dispatchEvent(new Event('resize')); 425 }, 10); 426 }; 427 })(); 428 429 $('body').on('click', '.mepr-signup-form div[class^=mepr-payment-method] input.mepr-form-radio', function () { 430 var form = $(this).closest('.mepr-signup-form'); 431 432 // Reset the transaction ID to prevent any issues after switching payment methods. 433 form.find('input[name="mepr_transaction_id"]').val(''); 434 435 // Fire event for gateways to react to payment method change. 436 form.trigger('meprPaymentMethodChanged', [$(this).val()]); 437 438 var pmid = '.mp-pm-desc-' + $(this).val(); 439 var pmid_exists = (form.find(pmid).length > 0); 440 441 form.find('.mepr-payment-method-desc-text').addClass('mepr-close'); 442 443 if(pmid_exists) { 444 form.find(pmid).removeClass('mepr-close'); 445 } 446 447 //If nothing has the mepr-close class, we still need to show this one's description 448 var mepr_close_exists = (form.find('.mepr-payment-method-desc-text.mepr-close').length > 0); 449 450 if(mepr_close_exists) { 451 form.find('.mepr-payment-method-desc-text.mepr-close').slideUp({ 452 duration: 200, 453 complete: function() { 454 // Clear validation errors on fields now hidden 455 form.find('.mepr-payment-methods-wrapper .mepr-form-input').each(function () { 456 $('.mepr-form-input.invalid').removeClass('.invalid'); 457 $('.cc-error').hide(); 458 $('.mepr-form-has-errors').hide(); 459 }); 460 461 if(pmid_exists) { 462 form.find(pmid).slideDown(200, windowResize); 463 } 464 } 465 }); 466 } else { 467 // Clear validation errors on fields now hidden 468 form.find('.mepr-payment-methods-wrapper .mepr-form-input').each(function () { 469 $('.mepr-form-input.invalid').removeClass('.invalid'); 470 $('.cc-error').hide(); 471 $('.mepr-form-has-errors').hide(); 472 }); 473 474 if(pmid_exists) { 475 form.find(pmid).slideDown(200, windowResize); 476 } 477 } 478 }); 479 480 // Update price string & invoice when certain inputs change value 481 $("body").on("change mepr-geolocated", 482 ".mepr-form .mepr-form-input, .mepr-form .mepr-form-radios-input, .mepr-form .mepr-select-field", 483 function () { 484 if($(this).attr('name') == 'mepr-address-zip' || 485 $(this).attr('name') == 'mepr-address-city' || 486 $(this).attr('name') == 'mepr-address-country' || 487 $(this).attr('name') == 'mepr-address-one' || 488 $(this).attr('name') == 'mepr-address-state' || 489 $(this).attr('name') == 'mepr_vat_customer_type' || 490 $(this).attr('name') == 'mepr_vat_number' || 491 $(this).attr('name') == 'mpgft-signup-gift-checkbox' 492 ) { 493 updateCheckoutState($(this).closest(".mepr-signup-form")); 494 } 495 } 496 ); 497 498 $(".mepr-replace-file").each(function(){ 499 $(this).closest('div').find('.mepr-file-uploader').hide(); 500 }); 501 $('body').on('click', '.mepr-replace-file', function (e) { 502 $(this).closest('div').find('.mepr-file-uploader').toggle(); 503 }); 504 505 // Set the visibility of payment methods based on order bumps 506 var handleOrderBumpToggle = function () { 507 var $input = $(this), 508 $order_bump = $input.closest('.mepr-order-bump'), 509 $order_bumps = $order_bump.closest('.mepr-order-bumps'), 510 $form = $order_bumps.closest('.mepr-signup-form'), 511 has_order_bump = false, 512 has_sub = false, 513 $to_hide = $(), 514 $to_show = $(), 515 $compatible_pm, 516 $incompatible_pm; 517 518 $order_bumps.find('input[name="mepr_order_bumps[]"]:checked').each(function () { 519 has_order_bump = true; 520 521 if($(this).closest('.mepr-order-bump').hasClass('mepr-sub')) { 522 has_sub = true; 523 } 524 }); 525 526 if ( $(this).hasClass('mepr_order_bumps_init') ) { 527 return; 528 } 529 530 var is_ob_required = $order_bump.hasClass('mepr-order-bump-required'); 531 532 if (is_ob_required) { 533 $(this).addClass('mepr_order_bumps_init'); 534 } 535 536 $form.find('.mepr-order-bumps-notice').removeClass('mepr_error').addClass('mepr-hidden'); 537 $form.removeClass('mepr-order-bumps-required-error'); 538
539 var $payment_method_inputs = $form.find('div[class^=mepr-payment-method] input.mepr-form-radio, input[type="hidden"][name="mepr_payment_method"]'); 540 541 $payment_method_inputs.each(function () { 542 var $pm = $(this); 543 544 if(has_order_bump) { 545 if($pm.hasClass('mepr-can-order-bumps')) { 546 if(has_sub) { 547 if($pm.hasClass('mepr-can-multiple-subscriptions')) { 548 $to_show = $to_show.add($pm); 549 550 if(!$compatible_pm) { 551 $compatible_pm = $pm; 552 } 553 } else { 554 $to_hide = $to_hide.add($pm); 555 556 if($pm.prop('checked')) { 557 $incompatible_pm = $pm; 558 } 559 } 560 } else { 561 $to_show = $to_show.add($pm); 562 563 if(!$compatible_pm) { 564 $compatible_pm = $pm; 565 } 566 } 567 } else { 568 $to_hide = $to_hide.add($pm); 569 570 if($pm.prop('checked')) { 571 $incompatible_pm = $pm; 572 } 573 } 574 } else { 575 $to_show = $to_show.add($pm); 576 } 577 }); 578 579 if($incompatible_pm && is_ob_required) { 580 $to_hide = $to_hide.add($incompatible_pm); 581 $to_hide.closest('.mepr_payment_method, .mepr-payment-option-label').hide() 582 } 583 584 if(!$to_show.length) { 585 if( is_ob_required ) { 586 // A real problem only when payment methods exist but none are compatible with the 587 // required bump. When none are rendered the checkout collects no payment (e.g. a 588 // coupon zeroed the total), so a required bump needs no gateway and submit proceeds. 589 if( $payment_method_inputs.length ) { 590 $form.find('.mepr-order-bumps-notice').text(MeprSignup.no_compatible_pms_ob_required).addClass('mepr_error').removeClass('mepr-hidden'); 591 $form.addClass('mepr-order-bumps-required-error'); 592 } 593 } else { 594 alert(MeprSignup.no_compatible_pms); 595 return false; 596 } 597 } 598 599 if($incompatible_pm) { 600 if($compatible_pm) { 601 var compatible_pm_label = $compatible_pm.data('payment-method-type'), 602 prompt = MeprSignup.switch_pm_prompt.replace('%s', compatible_pm_label); 603 604 if($.magnificPopup) { 605 var $switch_button = $('<div class="mepr-btn">').text(MeprSignup.switch_pm.replace('%s', compatible_pm_label)).on('click', function () { 606 $compatible_pm.trigger('click'); 607 $input.trigger('click'); 608 $.magnificPopup.close(); 609 }); 610 611 var $cancel_button = $('<div class="mepr-btn mepr-btn-secondary">').text(MeprSignup.cancel).on('click', function () { 612 $.magnificPopup.close(); 613 }); 614 615 var $popup_content = $('<div class="mepr-switch-pm-popup">').append( 616 $('<img class="mepr-switch-pm-popup-icon">').attr('src', MeprSignup.warning_icon_url), 617 $('<p>').text(prompt), 618 $('<div class="mepr-switch-pm-popup-buttons">').append($switch_button, $cancel_button) 619 ); 620 621 if( ! is_ob_required ) { 622 $.magnificPopup.open({ 623 mainClass: 'mepr-switch-pm-mfp', 624 items: { 625 src: $popup_content, 626 type: 'inline' 627 } 628 }); 629 } else { 630 $compatible_pm.trigger('click'); 631 $input.trigger('click'); 632 } 633 634 } else if(confirm(prompt)) { 635 $compatible_pm.trigger('click'); 636 $input.trigger('click'); 637 return; 638 } 639 } else { 640 if( is_ob_required ) { 641 $form.find('.mepr-order-bumps-notice').text(MeprSignup.no_compatible_pms_ob_required).addClass('mepr_error').removeClass('mepr-hidden'); 642 $form.addClass('mepr-order-bumps-required-error'); 643 } else { 644 alert(MeprSignup.no_compatible_pms); 645 } 646 } 647 648 return false; 649 } 650 651 $to_hide.closest('.mepr_payment_method, .mepr-payment-option-label').hide(); 652 $to_show.closest('.mepr_payment_method, .mepr-payment-option-label').show(); 653 654 $order_bump.toggleClass('mepr-order-bump-selected', this.checked); 655 }; 656 657 $('body').on('click', '.mepr-signup-form input[name="mepr_order_bumps[]"]', handleOrderBumpToggle); 658 659 if( $('.mepr-order-bump-required').length ) { 660 661 $('input[name="mepr_order_bumps[]"]:checked').each(function () { 662 handleOrderBumpToggle.call(this); 663 }); 664 665 if( $('.mepr-signup-form.mepr-order-bumps-required-error').length ) { 666 $('.mepr-signup-form').find('.mepr-submit').hide(); 667 $('.mepr-signup-form').find('.mepr-submit').attr('disabled','disabled'); 668 } else { 669 $('.mepr-signup-form').find('.mepr-submit').show(); 670 $('.mepr-signup-form').find('.mepr-submit').removeAttr('disabled'); 671 } 672 673 updateCheckoutState($('.mepr-signup-form')); 674 } 675 676 // Hide subscription order bumps if no payment method supports multiple subscriptions 677 $('.mepr-signup-form').each(function () { 678 var $form = $(this), 679 $order_bumps = $form.find('.mepr-order-bumps'), 680 pm_supports_multiple_subs = false;
681 682 if(!$order_bumps.length) { 683 return; 684 } 685 686 $form.find('div[class^=mepr-payment-method] input.mepr-form-radio, input[type="hidden"][name="mepr_payment_method"]').each(function (index) { 687 var $pm = $(this); 688 689 if($pm.hasClass('mepr-can-multiple-subscriptions') && pm_supports_multiple_subs === false) { 690 pm_supports_multiple_subs = index; 691 } 692 }); 693 694 if(pm_supports_multiple_subs === false) { 695 $order_bumps.find('.mepr-order-bump.mepr-sub').hide(); 696 697 if(!$order_bumps.find('.mepr-order-bump:visible').length) { 698 $order_bumps.hide(); 699 } 700 } else if(pm_supports_multiple_subs > 0) { 701 var $new_first_pm = $form.find('div[class^=mepr-payment-method] input.mepr-form-radio').eq(pm_supports_multiple_subs); 702 703 $new_first_pm 704 .closest('.mepr_payment_method, .mepr-payment-option-label') 705 .insertBefore( 706 $form.find('div[class^=mepr-payment-method] input.mepr-form-radio') 707 .eq(0) 708 .closest('.mepr_payment_method, .mepr-payment-option-label') 709 ); 710 711 $new_first_pm.trigger('click'); 712 } 713 714 // If gift checkbox is checked, hide and disable order bumps 715 if($form.find('input[name="mpgft-signup-gift-checkbox"]').is(':checked')) { 716 $order_bumps.hide().find('input[name="mepr_order_bumps[]"]').prop('checked', false); 717 } 718 }); 719 720 $("body").on("change", 721 '.mepr-form input[name="mepr_order_bumps[]"]', 722 function (e) { 723 let form = $(this).closest(".mepr-signup-form"); 724 if( $('input[type="hidden"][name="mepr_process_signup_form"]').length ) { 725 if( $('input[type="hidden"][name="mepr_process_signup_form"]').val() == 'Y' ) { 726 return; 727 } 728 } 729 updateCheckoutState(form); 730 } 731 ); 732 733 $("body").on('change', '.mepr-signup-form input[name="mpgft-signup-gift-checkbox"]', function () { 734 let $is_gift = $(this), 735 $form = $is_gift.closest('.mepr-signup-form'); 736 737 if ($is_gift.is(':checked')) { 738 $form.find('.mepr-order-bumps').hide().find('input[name="mepr_order_bumps[]"]:checked').prop('checked', false).each(function () { 739 handleOrderBumpToggle.call(this); 740 }); 741 } else { 742 $form.find('.mepr-order-bumps').show(); 743 } 744 }); 745 }); 746})(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.