PageSourceSearch

https://xr4rehab.org/wp-content/plugins/paid-member-subscriptions-…/js/pms-fd-front-end.js?ver=3.1.2

js xr4rehab.org collected 2026-10-09 21:46:45 UTC 15,125 bytes, 433 lines download raw bytes

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.