https://xr4rehab.org/wp-content/plugins/paid-member-subscriptions-…/js/pms-fd-front-end.js?ver=3.1.2
1jQuery(document).ready(function() { 2 3 // Style 2 only 4 if ( jQuery('.pms-form-design-wrapper.pms-form-style-2').length > 0 ) { 5 let billingStateField = jQuery('.pms-form-design-wrapper.pms-form-style-2 .pms-billing-details .pms-billing-state'); 6 7 if (billingStateField.length > 0) { 8 stateFieldLabelSpacing(billingStateField); 9 10 // Observe changes for the Billing State Field 11 const billingStateFieldObserver = new MutationObserver(() => { 12 stateFieldLabelSpacing(billingStateField); 13 }); 14 15 billingStateFieldObserver.observe(billingStateField[0], { 16 childList: true, 17 characterData: true, 18 subtree: true, 19 attributes: true 20 }); 21 } 22 23 } 24 25 // Style 3 only 26 if ( jQuery('.pms-form-design-wrapper.pms-form-style-3').length > 0 ) { 27 28 if ( jQuery('.pms-field-subscriptions > .pms-subscription-plan').length === 0 ) { 29 jQuery('.pms-field-subscriptions').css({ 30 'padding': '0', 31 'border': 'none' 32 }); 33 } 34 35 if ( jQuery('#pms_register-form .pms-form-fields-wrapper > .pms-gm-message, #pms_register-form .pms-form-fields-wrapper > .pms-gift-activation-message').length > 0 ) { 36 jQuery('#pms_register-form .pms-form-fields-wrapper .pms-field-subscriptions').css({ 37 'padding': '0', 38 'border': 'none' 39 }); 40 } 41 42 if ( jQuery('.pms-form-style-3 #pms-paygates-wrapper input.pms_pay_gate[type="hidden"]').length > 0 ) { 43 jQuery('.pms-form-style-3 #pms-paygates-wrapper').css({ 44 'padding': '0', 45 'border': 'none' 46 }); 47 } 48 49 jQuery('.pms-account-subscription-details-table').each(function() { 50 let lastTableRow = jQuery(this).find('tr:last-of-type'); 51 52 if ( lastTableRow.hasClass('pms-account-subscription-details-table__actions') ) { 53 lastTableRow.prev().addClass('last-table-row') 54 } else { 55 lastTableRow.addClass('last-table-row') 56 } 57 }); 58 59 } 60 61 62 jQuery('.pms-field input:disabled').parent().addClass('disabled-field'); 63 64 pmsHandleFloatingLabels(jQuery('.pms-field:not(.pms-field-subscriptions, .pms-gdpr-field, .pms-email-marketing-field, .pms-field-type-select, .pms-field-type-select_state, :has(input#pms-delete-account)), #pms-subscription-plans-discount, form#pms_login p.login-username, form#pms_login p.login-password, form#pms-invite-members')); 65 66 // Reinitialize PMS Form Design labels inside Elementor Popups 67 // - popup content is rendered after the initial page load handlers are attached 68 // - rerun the existing label setup only for PMS forms inside the opened popup 69 jQuery(document).on('elementor/popup/show', function (event, popupID) { 70 let elementorPopup = jQuery('#elementor-popup-modal-' + popupID); 71 72 if (elementorPopup.find('.pms-form-design-wrapper').length === 0) 73 return; 74 75 pmsHandleFloatingLabels(elementorPopup.find('.pms-field:not(.pms-field-subscriptions, .pms-gdpr-field, .pms-email-marketing-field, .pms-field-type-select, .pms-field-type-select_state, :has(input#pms-delete-account)), #pms-subscription-plans-discount, form#pms_login p.login-username, form#pms_login p.login-password, form#pms-invite-members')); 76 pmsFocusInOutSelectFields(elementorPopup.find('.pms-billing-details .pms-field-type-select, .pms-billing-details .pms-field-type-select_state')); 77 }); 78 79 pmsFocusInOutSelectFields(jQuery('.pms-billing-details .pms-field-type-select, .pms-billing-details .pms-field-type-select_state')); 80 81 jQuery('.pms-field.pms-field-subscriptions, .pms-upgrade__group').on('change', function(element) { 82 pmsHandleFloatingLabels(jQuery('.pms-billing-details .pms-field, #pms-subscription-plans-discount')); 83 pmsFocusInOutSelectFields(jQuery('.pms-billing-details .pms-field-type-select, .pms-billing-details .pms-field-type-select_state')); 84 }); 85 86 jQuery('#pms_user_email').on('change', function() { 87 pmsHandleFloatingLabels(jQuery('.pms-billing-details .pms-field.pms-billing-email')); 88 }); 89 90 jQuery('#pms_first_name').on('change', function() { 91 pmsHandleFloatingLabels(jQuery('.pms-billing-details .pms-field.pms-billing-first-name')); 92 }); 93 94 jQuery('#pms_last_name').on('change', function() { 95 pmsHandleFloatingLabels(jQuery('.pms-billing-details .pms-field.pms-billing-last-name')); 96 }); 97 98 99 // Observe changes for the Billing State Field 100 const stateBillingField = jQuery('.pms-form-design-wrapper .pms-billing-state'); 101 102 if (stateBillingField.length > 0) { 103 const stateBillingFieldObserver = new MutationObserver(() => { 104 pmsFocusInOutSelectFields(stateBillingField); 105 pmsHandleFloatingLabels(stateBillingField); 106 }); 107 108 stateBillingFieldObserver.observe(stateBillingField[0], { 109 childList: true, 110 subtree: true, 111 characterData: true 112 }); 113 } 114 115 116 if ( jQuery('.pms-form-design-wrapper nav.pms-account-navigation').length > 0 ) { 117 handleLogoutButtonPositioning() 118 } 119 120 121 if ( jQuery('#pms_register-form').length > 0 || 122 jQuery('#pms-register-form').length > 0 || 123 jQuery('#pms_new_subscription-form').length > 0 || 124 jQuery('#pms-change-subscription-form').length > 0 || 125 jQuery('#pms-renew-subscription-form').length > 0 || 126 jQuery('#pms-gift-subscription-form').length > 0 || 127 jQuery('#pms-retry-payment-subscription-form').length > 0 ) 128 { 129 // highlight the selected Subscription Plan 130 markSelectedSubscriptionPlan(); 131 132 // Adjusts the PMS Form layout responsively 133 adjustFormLayout(); 134 135 jQuery(window).on('resize', function () { 136 137 // Skip while an input is focused 138 // - mobile keyboard opens => fires "resize" => layout adjust steals focus 139 if (jQuery('.pms-form :input:focus').length) 140 return; 141 142 adjustFormLayout(); 143 }); 144 } 145 146}); 147 148 149/** 150 * Mark the selected Subscription Plan by adding the "selected" class to its label 151 */ 152function markSelectedSubscriptionPlan() { 153 let radioButtons = jQuery('input[name="subscription_plans"]'); 154 155 if ( radioButtons.length === 1 ) { 156 jQuery('.pms-field-subscriptions .pms-subscription-plan label').addClass("selected"); 157 } 158 else if ( radioButtons.length > 1 ) { 159 radioButtons.each(function() { 160 if (jQuery(this).is(":checked")) { 161 jQuery(this).closest("label").addClass("selected"); 162 } 163 }); 164 165 radioButtons.on("click", function() { 166 jQuery('label').removeClass('selected'); 167 jQuery(this).closest("label").addClass("selected"); 168 }); 169 } 170} 171 172 173/** 174 * Adjusts the PMS Form layout responsively 175 * 176 * Billing Fields: 177 * - on mobile version we need Billing Fields to be placed after the Payment Gateways section
178 * - on large screens we need to place the Billing Fields in the main form fields container so they will not be displayed in the payment sidebar 179 * 180 * Go Back button: 181 * - on mobile we need to add ot as the last form element 182 * - on large screens we need to add it to the main form fields container so it will not break the sidebar layout 183 * 184 * Payment Sidebar class: 185 * - add/remove "pms-form-design-wrapper--sidebar-showing" class as needed 186 * 187 */ 188function adjustFormLayout() { 189 190 // handle multiple PMS Forms on the same page 191 jQuery('.pms-form').each(function () { 192 193 let $form = jQuery(this); 194 195 // If form doesn't exist, nothing to do 196 if (!$form.length) { 197 return; 198 } 199 200 let isDesktopVersion = window.matchMedia("(min-width: 1191px)").matches, 201 billingFields = $form.find('.pms-billing-details'), 202 billingToggle = $form.find('.pms-section-billing-toggle'), 203 giftDetails = $form.find('.pms-section-gift-details'), 204 redirectBack = $form.find('input[name="pms_redirect_back"]'),
205 sidebarWrapper = $form.find('.pms-paygates-holder'), 206 mainWrapper = $form.find('.pms-form-fields-wrapper'), 207 subscriptionPlans = $form.find('.pms-subscription-plan'), 208 formWidth = $form.outerWidth(); 209 210 /** 211 * Sidebar shows only if the form is wider than 1020px: 212 * - prevents sidebar in narrow containers (e.g. Mobile View or Elementor/Gutenberg containers) 213 * - ensures left column is at least 470px (width of the sidebar) 214 * - includes 80px gap between columns 215 */ 216 if ( isDesktopVersion && formWidth > 1020 && subscriptionPlans.length > 0 ) { 217 218 // Billing Fields -> back to left column 219 if (billingFields.length) { 220 mainWrapper.append(billingFields); 221 } 222 223 // Gift Details -> back to left column 224 if (giftDetails.length) { 225 mainWrapper.append(giftDetails); 226 } 227 228 // Go Back button -> also into left column 229 if (redirectBack.length) { 230 mainWrapper.append(redirectBack); 231 } 232 233 $form.addClass( 'pms-form-design-wrapper--sidebar-showing'); 234 235 } 236 else { 237 238 let priceBreakdown = sidebarWrapper.find('.pms-price-breakdown__holder'), 239 formSubmit = sidebarWrapper.find('input[type="submit"]'); 240 241 // Move Billing Fields & Gift Details outside the sidebar container 242 if (sidebarWrapper.length) { 243 const target = priceBreakdown.length ? priceBreakdown : formSubmit; 244 245 [billingFields, giftDetails].forEach(function (element) { 246 247 if (!element.length) 248 return; 249 250 if (target.length) { 251 element.insertBefore(target); 252 } else { 253 sidebarWrapper.append(element); 254 } 255 256 }); 257 } 258 259 // Move Go Back button next to the Form Submit button 260 if (redirectBack.length && formSubmit.length) { 261 formSubmit.after(redirectBack); 262 } 263 264 $form.removeClass( 'pms-form-design-wrapper--sidebar-showing'); 265 266 } 267 268 // Position the Billing Fields Toggle right before the Billing Details section 269 // - Billing Details section is relocated to different containers, depending on the Payment Sidebar visibility 270 if (billingFields.length && billingToggle.length) { 271 billingFields.before(billingToggle); 272 } 273 274 }); 275 276} 277 278 279/** 280 * Handles Billing State Field Label spacing for Form Design - Style-2 281 * 282 */ 283function stateFieldLabelSpacing(stateField) { 284 let label = stateField.find('label'), 285 elementType = jQuery('#' + label.attr('for')).prop('nodeName'); 286 287 if (elementType === 'INPUT') 288 label.css('left', '30px'); 289 else stateField.find('label').css('left', '0'); 290} 291 292 293/** 294 * Handles Floating Labels 295 */ 296function pmsHandleFloatingLabels (formFields) { 297 298 formFields.each(function () { 299 300 let field = jQuery(this), 301 input = field.find('input'), 302 textarea = field.find('textarea'), 303 label = field.find('label'), 304 inviteMembers = jQuery('form#pms-invite-members'); 305 306 if (textarea.length > 0 && (field[0] === inviteMembers[0] || input.length === 0)) { 307 input = textarea; 308 } 309 310 if ( field.find('.pms_field-errors-wrapper').length > 0 ) { 311 field.addClass('pms-field-error'); 312 } 313 else { 314 field.removeClass('pms-field-error'); 315 } 316 317 // Authorize.Net on PMS forms only (not Profile Builder â WPPB hides placeholders and uses the floating label). 318 let keepLabelActiveWhenEmpty = input.is('.pms-authorize-net-field') 319 && input.attr('placeholder') 320 && field.closest('.wppb-user-forms').length === 0; 321 322 if ( input.val() || keepLabelActiveWhenEmpty ) 323 label.addClass('active'); 324 325 input.focusin(function () { 326 label.addClass('active focused'); 327 // label.addClass('focused'); 328 329 }) 330 331 input.focusout(function () { 332 label.removeClass('focused'); 333 checkInput(); 334 }) 335 336 setTimeout(function() { 337 checkInput(); 338 }, 750); 339 340 /** 341 * Mark Labels as needed 342 * 343 */ 344 function checkInput() { 345 if ( input.val() || keepLabelActiveWhenEmpty ) { 346 label.addClass('active'); 347 } 348 else if (!input.is(':focus')) { 349 label.removeClass('active'); 350 } 351 } 352 353 }); 354 355} 356 357 358/** 359 * Handles Select Field Label (focus in/out on Field Labels) 360 */ 361function pmsFocusInOutSelectFields(formFields) { 362 363 formFields.each(function () { 364 let field = jQuery(this), 365 select = field.find('select'), 366 label = field.find('label'); 367 368 if ( select.val() ) { 369 label.addClass('active'); 370 } 371 372 if ( !select.val() || select.val().length === 0) { 373 label.removeClass('active'); 374 } 375 376 field.focusin(function () { 377 label.addClass('active focused'); 378 }); 379 380 field.focusout(function () { 381 label.removeClass('focused'); 382 checkSelect(); 383 }) 384 385 field.click(function (e) { 386 if ( jQuery(e.target).parents('.wppb_bdp_visibility_settings').length === 0 ) 387 label.addClass('focused'); 388 }) 389 390 select.change(function() { 391 checkSelect(); 392 }) 393 394 setTimeout(function() { 395 checkSelect(); 396 }, 750); 397 398 /** 399 * Mark Fields and Labels as needed 400 * 401 */ 402 function checkSelect() { 403 if ( (select.val() && select.val().length >
403 0) || ( field.is('.pms-field-type-select_state') && field.find('input').val() ) ){ 404 label.addClass('active'); 405 } 406 else { 407 label.removeClass('active'); 408 } 409 } 410 }) 411 412} 413 414 415/** 416 * Handles Logout Button positioning for a crowded PMS Account navigation bar 417 */ 418function handleLogoutButtonPositioning() { 419 let containerWidth = jQuery('.pms-form-design-wrapper nav.pms-account-navigation').outerWidth(true), 420 navTabs = jQuery('.pms-form-design-wrapper nav.pms-account-navigation ul li'), 421 tabsNumber = navTabs.length, 422 totalTabsWidth = 0; 423 424 navTabs.each(function() { 425 totalTabsWidth += jQuery(this).outerWidth(true); 426 }); 427 428 if ( totalTabsWidth > 0 ) 429 totalTabsWidth += (tabsNumber - 1) * 40; // 40px is the gap between the Navigation Tabs 430 431 if (totalTabsWidth > containerWidth) 432 jQuery('.pms-form-design-wrapper nav.pms-account-navigation .pms-account-navigation-link--logout').css('position', 'unset'); 433}
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.