PageSourceSearch

https://www.autismeurope.org/wp-content/plugins/paid-member-subscr…/js/frontend-discount-code.js?ver=3.0.9

js autismeurope.org collected 2026-09-24 17:34:57 UTC 14,433 bytes, 334 lines download raw bytes

1/*
2 * JavaScript for front-end discount code display
3 *
4 */
5jQuery(document).ready(function($) {
6
7    // Cache the value of the last checked discount code
8    var last_checked_discount_code;
9
10    /*
11     * Show / Hide discount code field if a free plan is selected
12     *
13     */
14    toggle_discount_box( $('input[name=subscription_plans][type=radio]').length > 0 ? $('input[name=subscription_plans][type=radio]:checked') : $('input[name=subscription_plans][type=hidden]') )
15
16    /**
17     * Trigger automatically "Apply" discount button when the user already entered a discount code and selects another subscription plan, or checks the "Automatically renew subscription" checkbox.
18     * This will update the discount message shown below the field.
19     *
20     */
21    $(document).on('click', '.pms-subscription-plan input[type="radio"][name="subscription_plans"]', function(){
22
23        // If subscription is not free and discount code field is not empty
24        if (($(this).attr("data-price") > 0) && ($('#pms_subscription_plans_discount_code').length > 0)) {
25
26            $('#pms-apply-discount').trigger('click')
27
28        } else {
29
30            $('#pms-subscription-plans-discount-messages-wrapper').hide()
31            $('#pms-subscription-plans-discount-messages').hide()
32
33        }
34
35        toggle_discount_box( $(this) )
36
37    })
38
39    $(document).on('click', '.pms-subscription-plan-auto-renew input[type="checkbox"][name="pms_recurring"]', function () {
40
41        // If discount code field is not empty
42        if ( $('#pms_subscription_plans_discount_code').length > 0 ){
43
44            $('#pms-apply-discount').trigger('click')
45
46        } else {
47
48            $('#pms-subscription-plans-discount-messages-wrapper').hide()
49            $('#pms-subscription-plans-discount-messages').hide()
50
51        }
52
53        toggle_discount_box( $($pms_checked_subscription) )
54
55    })
56    
57    /**
58     * Toggle discount code box when the subscription plans field is shown from the
59     * Profile Builder Conditional Logic functionality
60     */
61    $(document).on("wppbAddRequiredAttributeEvent", function (e) {
62        if ($(e.target).is('#pms_subscription_plans_discount_code'))
63            toggle_discount_box($('input[name=subscription_plans][type=radio]').length > 0 ? $('input[name=subscription_plans][type=radio]:checked') : $('input[name=subscription_plans][type=hidden]'))
64    })
65
66    /**
67     * Handles discount code validation when the user clicks the "Apply" discount button
68     *
69     */
70    $(document).on('click', '#pms-apply-discount', function(e){
71
72        e.preventDefault();
73
74        // If undefined, cache the parent form
75        if( typeof $pms_form == 'undefined' )
76            $pms_form = $(this).closest('form');
77
78        var $subscription_plan = '';
79
80        $('.pms-subscription-plan input[type="radio"]').each(function(){
81            if($(this).is(':checked')){
82                $subscription_plan = $(this);
83            }
84        });
85
86        if( $subscription_plan == '' ) {
87            $subscription_plan = $('input[type=hidden][name=subscription_plans]');
88        }
89
90        if( $('#pms_subscription_plans_discount_code').val() == '' ) {
91            $('#pms-subscription-plans-discount-messages-wrapper').fadeOut( 350 );
92
93            // empty the message HTML alongside the fadeOut so the previous success/error text does not linger in the DOM after a clear
94            $('#pms-subscription-plans-discount-messages').fadeOut( 350 ).empty().removeClass( 'pms-discount-success pms-discount-error' )
95
96            reset_discounted_plan_data( $subscription_plan )
97            jQuery(document).trigger( 'pms_discount_error', [ null, $subscription_plan, $pms_form ] )
98
99            return false;
100        }
101
102        // Cache the discount code
103        last_checked_discount_code = $('#pms_subscription_plans_discount_code').val();
104
105        pwyw_price = '';
106
107        if ( $('input[name="subscription_price_'+$subscription_plan.val()+'"]').length != 0 )
108            pwyw_price = $('input[name="subscription_price_'+$subscription_plan.val()+'"]').val();
109
110        var data = {
111            'action'                  : 'pms_discount_code',
112            'code'                    : $.trim( $('#pms_subscription_plans_discount_code').val()),
113            'subscription'            : $subscription_plan.val(),
114            'recurring'               : $('input[name="pms_recurring"]:checked').val(),
115            'pwyw_price'              : pwyw_price,
116            'pmstkn_original'         : $pms_form.find('input[name="pmstkn"]').val(),
117            'pms_current_subscription': $pms_form.find('input[name="pms_current_subscription"]').val(),
118            'form_action'             : $pms_form.find('input[name="form_action"]').val(),
119        };
120
121        // addons that extend checkout with additional purchasable items can hook this filter to inject fields into the AJAX request (e.g. Order Bumps appends pms_order_bumps[] plus form-submit field name mirrors so the server-side bundle pipeline reads the same composition)
122        var augmentedData = $(document).triggerHandler( 'pms_filter_discount_ajax_payload', [ data, $pms_form ] );
123
124        if( augmentedData && typeof augmentedData === 'object' )
125            data = augmentedData;
126
127        var currency  = new URLSearchParams(window.location.search).get('pms_mc_currency');
128
129        if ( currency )
130            data['pms_mc_currency'] = currency;
131
132        if( data.pmstkn_original === undefined && jQuery( '.wppb-register-user' ).length > 0 )
133            data.pmstkn_original = 'pb_form'
134
135        // Make sure it's not an empty discount
136        if ( data['code'] !== '' ) {
137
138            $('#pms-subscription-plans-discount-messages').hide()
139            $('#pms-subscription-plans-discount-messages-wrapper').show()
140            $('#pms-subscription-plans-discount-messages-loading').fadeIn(350)
141
142            // let add-ons attach extra context to the request before it is sent
143            // - the data object is passed by reference, so handlers mutate it in place (e.g. the Group add-on adds the selected plan i
143d and seat count so per-seat plans are priced server-side)
144            jQuery( document ).trigger( 'pms_discount_code_request_data', [ data ] )
145
146            // We can also pass the url value separately from ajaxurl for front end AJAX implementations
147            jQuery.post(pms_discount_object.ajax_url, data, function (response) {
148
149                if (response.success != undefined) {
150
151                    // Add success message
152                    $('#pms-subscription-plans-discount-messages').removeClass('pms-discount-error')
153                    $('#pms-subscription-plans-discount-messages').addClass('pms-discount-success')
154
155                    $('#pms-subscription-plans-discount-messages-loading').fadeOut(350, function () {
156                        $('#pms-subscription-plans-discount-messages').html(response.success.message).fadeIn(350)
157                    })
158
159                    // Hide payment fields
160                    if (response.is_full_discount)
161                        $.pms_hide_payment_fields( $pms_form )
162                    else
163                        $.pms_show_payment_fields( $pms_form )
164
165                    // Cache the initial values only once so they can be restored after the discount is removed
166                    if ( !$subscription_plan.data('discounted-price') )
167                        $subscription_plan.data( 'price-original', $subscription_plan.data('price') )
168
169                    // Cache the initial MC amount only once so it can be restored after the discount is removed
170                    if ( !$subscription_plan.data('discounted-price') && typeof $subscription_plan.data('mc_price') != 'undefined' )
171                        $subscription_plan.data( 'mc-price-original', $subscription_plan.data('mc_price') )
172
173                    // Keep the MC amount in sync so Tax and gateway JS use the discounted value too
174                    if ( typeof $subscription_plan.data('mc_price') != 'undefined' )
175                        $subscription_plan.data( 'mc_price', response.discounted_price )
176
177                    $subscription_plan.data( 'price', response.discounted_price )
178                    $subscription_plan.data( 'discounted-price', true )
179                    $subscription_plan.data( 'discounted-price-value', response.original_discounted_price )
180
181                    if( response.is_full_discount == true ){
182                        
183                        if( response.recurring_payments == 1 ){
184                            $( 'input[name="pms_recurring"]', $pms_auto_renew_field ).prop( 'checked', true )
185                            $pms_auto_renew_field.hide()
186                        }
187
188                        $subscription_plan.data( 'is-full-discount', true )
189
190                    } else
191                        $subscription_plan.data( 'is-full-discount', false )
192
193                    $subscription_plan.data( 'discount-recurring-payments', response.recurring_payments )
194
195                    // listeners receive the response, the primary input and the form so addons that augment the AJAX response (e.g. Order Bumps' bundle_items per-item breakdown) can apply their own data-attribute updates before downstream consumers (order summary, gateways) react
196                    jQuery(document).trigger( 'pms_discount_success', [ response, $subscription_plan, $pms_form ] )
197
198                }
199
200                if (response.error != undefined) {
201
202                    // Add error message
203                    $('#pms-subscription-plans-discount-messages').removeClass('pms-discount-success')
204                    $('#pms-subscription-plans-discount-messages').addClass('pms-discount-error')
205
206                    $('#pms-subscription-plans-discount-messages-loading').fadeOut(350, function () {
207                        $('#pms-subscription-plans-discount-messages').html(response.error.message).fadeIn(350)
208                    })
209
210                    // Show payment fields
211                    $.pms_show_payment_fields( $pms_form )
212
213                    reset_discounted_plan_data( $subscription_plan )
214
215                    jQuery(document).trigger( 'pms_discount_error', [ response, $subscription_plan, $pms_form ] )
216
217                }
218
219            });
220        } else {
221
222            reset_discounted_plan_data( $subscription_plan )
223
224            jQuery(document).trigger( 'pms_discount_error' )
225
226        }
227
228    })
229
230    /**
231     * If there is a discount code value already set on document ready
232     * apply it
233     *
234     */
235    if( $('input[name=discount_code]').val() != '' )
236        $('#pms-apply-discount').trigger('click')
237
238    /**
239     * When losing focus of the discount code field, directly apply the discount
240     *
241     */
242    $('input[name=discount_code]').on( 'blur', function() {
243
244        if( last_checked_discount_code != $('input[name=discount_code]').val() )
245            $('#pms-apply-discount').trigger('click');
246
247        if ( $('input[name=discount_code]').val() == '' )
248            $.pms_show_payment_fields( $pms_form );
249    })
250
251    /*
252     * Show / Hide discount code field if a free plan is selected
253     *
254     */
255    function toggle_discount_box( $element ) {
256
257        if( !$element )
258            return
259
260        var selector = '#pms-subscription-plans-discount';
261        
262        if( !subscription_has_discount( $element.val() ) )
263            $(selector).hide()
264        else {
265            if ( $element.attr('data-price') == '0' ) {
266
267                if ( $.isFunction( $.pms_plan_is_prorated ) && $.pms_plan_is_prorated( $element ) ) {
268
269                    if ( $('input[name="pms_recurring"]', $('.pms-subscription-plan-auto-renew') ).prop('checked') || $element.data('recurring') == 2 ){
270                        $(selector).show()
271                        return
272                    }
273
274                }
275
276                if ( $.isFunction( $.pms_plan_has_signup_fee ) && $.pms_plan_has_signup_fee( $element ) )
277                    $(selector).show()
278
279                $(selector).hide()
280
281            } else {
282                $(selector).show()
283            }
284        }
285
286    }
287
288    function subscription_has_discount( subscription_id ){
289
290        // show the box if we don't have data available (old default)
291        if( typeof pms_discount_object == 'undefined' || typeof pms_discount_object.discounted_subscriptions == 'undefined' )
292            return true
293
294        let return_value  = false
295        let subscriptions = JSON.parse( pms_discount_object.discounted_subscriptions )
296
297        for ( var subscription in subscriptions ){
298            if( subscription_id == subscriptions[subscription] )
299                return_value = true
300        }
301
302        // bundle-aware addons (e.g. Order Bumps) can override the decision so the discount box stays visible when a selected bump has a targeting discount even if the primary plan does not
303        let filtered = $( document ).triggerHandler( 'pms_filter_subscription_has_discount', [ return_value, subscription_id ] )
304
305        return typeof filtered === 'boolean' ? filtered : return_value
306
307    }
308
309
310    // addons can request a fresh visibility check when their state changes (e.g. Order Bumps toggling a bump that has a targeting discount); re-run toggle_discount_box against the currently selected primary plan
311    $( document ).on( 'pms_recheck_discount_box_visibility', function() {
312        toggle_discount_box( $('input[name=subscription_plans][type=radio]').length > 0 ? $('input[name=subscription_plans][type=radio]:checked') : $('input[name=subscription_plans][type=hidden]') )
313    } )
314
315    /**
316     * Restore the initial plan values after a discount is removed or becomes invalid
317     * - used by the error and reset paths after the discount code is applied
318     */
319    function reset_discounted_plan_data( $subscription_plan ) {
320
321        if ( typeof $subscription_plan.data('price-original') != 'undefined' )
322            $subscription_plan.data( 'price', $subscription_plan.data('price-original') )
323
324        if ( typeof $subscription_plan.data('mc-price-original') != 'undefined' )
325            $subscription_plan.data( 'mc_price', $subscription_plan.data('mc-price-original') )
326
327        $subscription_plan.data( 'discounted-price', false )
328        $subscription_plan.data( 'discounted-price-value', 0 )
329        $subscription_plan.data( 'discount-recurring-payments', 0 )
330        $subscription_plan.data( 'is-full-discount', false )
331
332    }
333
334});

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.