PageSourceSearch

https://meditationinrhodeisland.org/wp-content/plugins/woocommerce…/js/one-page-checkout.js?ver=1.0

js meditationinrhodeisland.org collected 2026-10-06 20:29:15 UTC 18,576 bytes, 629 lines download raw bytes

1/*
2 * One Page Checkout JS: add/remove items from a One Page Checkout page via Ajax
3 */
4jQuery( document ).ready(
5	function($){
6
7		var response_messages = '';
8		var timeout;
9		var delay = 700;
10
11		var $checkout = $( '.checkout' );
12		var $body     = $( 'body' );
13		/**
14		 * Review Order Template Item Management (Removal & Quantity Adjustment)
15		 */
16
17		// Quantity buttons
18		$checkout.on(
19			'input',
20			'#order_review .opc_cart_item div.quantity input.qty',
21			function(e) {
22
23				var input = $( this ),
24				selectors = '.checkout #order_review .opc_cart_item div.quantity input.qty';
25
26				const quantity = input.val();
27
28				clearTimeout( timeout );
29
30				if ( quantity === '' ) {
31					return;
32				}
33
34				timeout = setTimeout(
35					function() {
36
37						var data = {
38							quantity,
39							add_to_cart: parseInt( input.closest( '.opc_cart_item' ).data( 'add_to_cart' ) ),
40							update_key:  input.closest( '.opc_cart_item' ).data( 'update_key' ),
41							nonce:       wcopc.wcopc_nonce,
42						};
43
44						if ( data['quantity'] == 0 ) {
45							data['action'] = 'pp_remove_from_cart';
46						} else {
47							data['action'] = 'pp_update_add_in_cart';
48						}
49
50						input.ajax_add_remove_product( data, e, selectors );
51
52					},
53					delay
54				);
55
56				e.preventDefault();
57
58			}
59		);
60
61		// handle blur with empty value
62		$checkout.on(
63			'blur',
64			'#order_review .opc_cart_item div.quantity input.qty',
65			function () {
66				const input    = $( this );
67				const quantity = input.val();
68				// the previous value is still stored in value attribute on input
69				if ( quantity === '' ) {
70					input.val( input.attr( 'value' ) );
71				}
72			}
73		);
74
75		// Remove buttons
76		$checkout.on(
77			'click',
78			'#order_review .opc_cart_item a.remove',
79			function(e) {
80
81				var data  = {
82					action:      'pp_remove_from_cart',
83					add_to_cart: parseInt( $( this ).closest( '.opc_cart_item' ).data( 'add_to_cart' ) ),
84					update_key:  $( this ).closest( '.opc_cart_item' ).data( 'update_key' ),
85					nonce:       wcopc.wcopc_nonce,
86				},
87				selectors = '.checkout #order_review .opc_cart_item a.remove';
88
89				$( this ).ajax_add_remove_product( data, e, selectors );
90
91				e.preventDefault();
92
93			}
94		);
95
96		/**
97		 * Single Product Template
98		 */
99
100		/* Add/remove products with button element or a tags */
101		$( '#opc-product-selection button.single_add_to_cart_button, .wcopc-product-single button.single_add_to_cart_button' ).on(
102			'click',
103			function(e) {
104
105				e.preventDefault();
106
107				var is_variable = $( this ).closest( '.variations_form' ).find( 'input[name="variation_id"]' ).length === 1,
108				is_grouped      = $( this ).siblings( '.group_table' ).length >= 1,
109				add_to_cart_id  = $( this ).closest( '.cart' ).find( '[name="add-to-cart"]' ).val(),
110				has_quantity    = $( this ).closest( '.cart' ).find( 'input[name="quantity"]' ).length === 1,
111				data            = {
112					action:       'pp_add_to_cart',
113					nonce:        wcopc.wcopc_nonce,
114					input_data:   $( this ).closest( '.product-quantity, .wcopc-product-single form' ).find( 'input[name!="variation_id"][name!="product_id"][name!="add-to-cart"][name!="quantity"], select, textarea' ).serialize(),
115				},
116				selectors       = '#opc-product-selection button.single_add_to_cart_button, .wcopc-product-single button.single_add_to_cart_button';
117
118				// Do not attempt the ajax call if the add to cart product ID is undefined.
119				if ( 'undefined' === typeof add_to_cart_id ) {
120					return;
121				}
122
123				if ( is_grouped ) {
124
125					data.add_to_cart = [];
126
127					$( this ).siblings( '.group_table' ).find( 'input[name^="quantity"]' ).each(
128						function( index, value ) {
129
130							if ( ( ! $( this ).is( ':checkbox' ) && $( this ).val() > 0 ) || ( $( this ).is( ':checkbox' ) && $( this ).is( ':checked' ) ) ) {
131
132								  var product_id = parseInt( $( this ).attr( 'name' ).match( /quantity\[(\d+)\]/ )[1] ),
133								 quantity        = parseInt( $( this ).val() );
134
135								data.add_to_cart.push(
136									{
137										'product_id': product_id,
138										'quantity':   quantity,
139									}
140								);
141							}
142						}
143					);
144
145					data.add_to_cart.forEach(
146						function(add_to_cart_data) {
147
148							data.add_to_cart = parseInt( add_to_cart_data.product_id );
149							data.quantity    = parseInt( add_to_cart_data.quantity );
150
151							$( this ).ajax_add_remove_product( data, e, selectors, false );
152						}
153					);
154
155				} else {
156
157					data.add_to_cart = parseInt( add_to_cart_id );
158
159					if ( is_variable ) {
160						data.variation_id = parseInt( $( this ).closest( '.variations_form' ).find( 'input[name="variation_id"]' ).val() );
161					}
162
163					// The quantity input field might be missing if a product is sold individually or has only 1 unit of stock remaining
164					if ( has_quantity ) {
165						data.quantity = parseInt( $( this ).closest( '.cart' ).find( 'input[name="quantity"]' ).val() );
166					}
167
168					$( this ).ajax_add_remove_product( data, e, selectors );
169				}
170
171				e.preventDefault();
172			}
173		);
174
175		/**
176		 * Other Templates
177		 */
178
179		/* Add/remove products with number input type */
180		$( '#opc-product-selection input[type="number"][data-add_to_cart]' ).on(
181			'input',
182			function(e) {
183				var input = $( this ),
184				selectors = '#opc-product-selection input[type="number"][data-add_to_cart]';
185
186				const quantity = input.val();
187
188				clearTimeout( timeout );
189
190				if ( quantity === '' ) {
191					return;
192				}
193
194				timeout = setTimeout(
195					function() {
196
197						var data = {
198							quantity,
199							add_to_cart: parseInt( input.data( 'add_to_cart' ) ),
200							input_data:  input.closest( '.product-quantity' ).find( 'input[name!="product_id"], select, textarea' ).serialize(),
201							nonce:       wcopc.wcopc_nonce,
202						};
203
204						if ( data['quantity'] == 0 ) {
205							data['action'] = 'pp_remove_from_cart';
206						} else {
207							data['action'] = 'pp_update_add_in_cart';
208						}
209
210						input.ajax_add_remove_product( data, e, selectors );
211
212					},
213					delay
214				);
215
216				e.preventDefault();
217
218			}
219		);
220
221		// handle blur with empty value for the input above
222		$( '#opc-product-selection input[type="number"][data-add_to_cart]' ).on(
223			'blur',
224			function () {
225				const input    = $( this );
226				const quantity = input.val();
227				// the previous value is still stored in value attribute on input
228				if ( quantity === '' ) {
229					input.val( input.attr( 'value' ) );
230				}
231			}
232		);
233
234		/* Add/remove products with radio or checkbox inputs */
235		$( '#opc-product-selection input[type="radio"][data-add_to_cart], #opc-product-selection input[type="checkbox"][data-add_to_cart]' ).on(
236			'change',
237			function(e) {
238
239				var input = $( this ),
240				selectors = '#opc-product-selection input[type="radio"][data-add_to_cart], #opc-product-selection input[type="checkbox"][data-add_to_cart]';
241
242				clearTimeout( timeout );
243
244				timeout = setTimeout(
245					function() {
246
247						var data = {
248							add_to_cart: parseInt( input.data( 'add_to_cart' ) ),
249							nonce:       wcopc.wcopc_nonce
250						};
251
252						if ( input.is( ':checked' ) ) {
253
254							if ( input.prop( 'type' ) == 'radio' ) {
255
256								data.empty_cart = 'true';
257								$( 'input[data-add_to_cart]' ).prop( 'checked', false );
258								input.prop( 'checked', true );
259								$( '.selected' ).removeClass( 'selected' );
260							}
261
262							data.action = 'pp_add_to_cart';
263							input.parents( '.product-item' ).addClass( 'selected' );
264
265						} else {
266
267							data.action = 'pp_remove_from_cart';
268							input.parents( '.product-item' ).removeClass( 'selected' );
269
270						}
271
272						input.ajax_add_remove_product( data, e, selectors );
273
274					},
275					delay
276				);
277
278			}
279		);
280
281		/* Add/remove products with button element or a tags */
282		$( '#opc-product-selection a[data-add_to_cart], #opc-product-selection button[data-add_to_cart]' ).on(
283			'click',
284			function(e) {
285
286				var data  = {
287					add_to_cart: parseInt( $( this ).data( 'add_to_cart' ) ),
288					nonce:       wcopc.wcopc_nonce,
289					input_data:  $( this ).closest( '.product-quantity' ).find( 'input[name!="product_id"], select, textarea' ).serialize(),
290				},
291				selectors = '#opc-product-selection a[data-add_to_cart], #opc-product-selection button[data-add_to_cart]';
292
293				// Toggle button on or off
294				if ( ! $( this ).parents( '.product-item' ).hasClass( 'selected' ) ) {
295					data.action = 'pp_add_to_cart';
296					$( this ).parents( '.product-item' ).addClass( 'selected' );
297				} else {
298					data.action = 'pp_remove_from_cart';
299					$( this ).parents( '.product-item' ).removeClass( 'selected' );
300				}
301
302				$( this ).ajax_add_remove_product( data, e, selectors );
303			}
304		);
305
306		/* Add products from any Easy Pricing Table template */
307		$( 'a.ptp-button, a.ptp-dg5-button, a.ptp-dg6-button, a.ptp-dg7-button, a.ptp-fancy-button, a.btn.sign-up, .ptp-stylish-pricing_button a, .ptp-design4-col > a' ).on(
308			'click',
309			function(e) {
310
311				var productParams = getUrlsParams( $( this )[0].search.substring( 1 ) ),
312				selectors         = 'a.ptp-button, a.ptp-dg5-button, a.ptp-dg6-button, a.ptp-dg7-button, a.ptp-fancy-button, a.btn.sign-up, .ptp-stylish-pricing_button a, .ptp-design4-col > a';
313
314				var data = {
315					action:      'pp_add_to_cart',
316					add_to_cart: productParams['add-to-cart'],
317					empty_cart:  'true',
318					nonce:       wcopc.wcopc_nonce
319				};
320
321				delete productParams['add-to-cart'];
322				data.input_data = $.param( productParams );
323
324				$( this ).ajax_add_remove_product( data, e, selectors );
325			}
326		);
327
328		// Set response messages when the checkout is fully updated (because it would remove them if we set them before that)
329		$body.on(
330			'updated_checkout',
331			function(){
332				if ( response_messages.length > 0 ) {
333					var $opc_messages = $( '#opc-messages' );
334
335					$opc_messages.prepend( response_messages );
336
337					if ( 'yes' === wcopc.autoscroll && ! $opc_messages.visible() ) {
338						$( 'html, body' ).animate(
339							{
340								scrollTop: ($opc_messages.offset().top - 150 )
341							},
342							500
343						);
344					}
345
346					response_messages = '';
347				}
348			}
349		);
350
351		/* Function to add or remove product from cart via an ajax call */
352		$.fn.ajax_add_remove_product = function( data, e, selectors, async_ajax ) {
353
354			// Default to synchonus Ajax, but for Grouped products, use async
355			async_ajax = ( typeof async_ajax !== 'undefined' ) ? async_ajax : true;
356
357			// Guard against race conditions by disabling the inputs
358			$( selectors ).attr( 'disabled', 'disabled' );
359
360			// Custom event for devs to hook into before posting of products for processing
361			$( 'body' ).trigger( 'opc_add_remove_product', [ data, e, selectors ] );
362
363			// Read from opc_add_remove_product trigger above and maybe avoid the AJAX add to cart call.
364			if ( data.invalid === true ) {
365				$( selectors ).removeAttr( 'disabled' );
366				return;
367			}
368
369			$.ajax(
370				{
371					type: 'POST',
372					url:   wcopc.ajax_url,
373					data:  data,
374					async: async_ajax,
375					dataType: 'json',
376					success: function( response, status, xhr ) {
377
378						var fragments;
379
380						try {
381
382							if ( response === '-1' ) {
383								throw 'invalid response';
384							}
385
386							if (xhr.getResponseHeader( 'Content-Type' ) == 'application/json') {
387								response = $.parseJSON( response );
388							}
389
390							// Get fragments
391							fragments = response.fragments;
392
393							var inputs = $( '#opc-product-selection [data-add_to_cart]' );
394
395							inputs.each(
396								function( index, value ) {
397
398									var product_id = $( this ).data( 'add_to_cart' ),
399									in_cart        = false;
400
401									$.each(
402										response.products_in_cart,
403										function( cart_item_id, cart_item_data ) {
404											if ( ( product_id == cart_item_id || product_id == cart_item_data.product_id ) ) {
405												  in_cart = true;
406											}
407										}
408									);
409
410									if ( $( this ).prop( 'type' ) == 'number' ) {
411
412										if ( in_cart ) {
413											$( this ).val( response.products_in_cart[ product_id ].quantity ).data( 'cart_quantity', response.products_in_cart[ product_id ].quantity );
414										} else {
415											$( this ).val( 0 ).data( 'cart_quantity', 0 );
416										}
417
418									} else if ( $( this ).is( 'a, button' ) ) {
419
420										if ( in_cart ) {
421											$( this ).parents( '.product-item' ).addClass( 'selected' );
422										} else {
423											 $( this ).parents( '.product-item' ).removeClass( 'selected' );
424										}
425
426									} else {
427
428										if ( in_cart ) {
429											$( this ).prop( 'checked', true );
430										} else {
431											$( this ).prop( 'checked', false );
432											$( this ).parents( '.product-item' ).removeClass( 'selected' );
433										}
434									}
435
436								}
437							);
438
439							// Store messages for use when checkout has finished updating
440							response_messages = response.messages;
441
442						} catch ( err ) {
443
444							if ( 'undefined' == typeof response.messages ) {
445								response_messages = wcopc.ajax_error_notice;
446							} else {
447								response_messages = response.messages;
448							}
449
450							var $opc_messages = $( '#opc-messages' );
451							$opc_messages.prepend( response.messages );
452
453							$( 'html, body' ).animate(
454								{
455									scrollTop: ( $opc_messages.offset().top - 50 )
456								},
457								500
458							);
459						}
460
461						$( '#opc-messages .woocommerce-error, #opc-messages .woocommerce-message, #opc-messages .woocommerce-info' ).remove();
462
463						// remove 'loading' class that Flatsome theme adds
464						$( 'button.single_add_to_cart_button' ).removeClass( 'loading' );
465
466						// Custom event for devs to hook into after products have been processed
467						$body.trigger( 'after_opc_add_remove_product', [ data, response ] );
468
469						// Tell WooCommerce to update totals
470						$body.trigger( 'update_checkout' );
471
472						// Block fragments class
473						if ( fragments ) {
474							$.each(
475								fragments,
476								function( key, value ) {
477									$( key ).addClass( 'updating' );
478								}
479							);
480						}
481
482						// Block fragments
483						var $updating = $( '.updating' );
484						$updating.fadeTo( '400', '0.6' ).block(
485							{
486								message: null,
487								overlayCSS: {
488									opacity: 0.6
489								}
490							}
491						);
492
493						// Replace fragments
494						if ( fragments ) {
495							$.each(
496								fragments,
497								function( key, value ) {
498									$( key ).replaceWith( value );
499								}
500							);
501						}
502
503						// Unblock
504						$updating.stop( true ).css( 'opacity', '1' ).unblock();
505
506						// It is now safe to change the cart again
507						$( selectors ).removeAttr( 'disabled' );
508
509					} }
510			);
511
512			e.preventDefault();
513		};
514
515		/* Only display the place order button when a product has been selected */
516		showHidePlaceOrder();
517
518		/* Append "Complete Order" anchor and "data-add_to_cart" attribute to single-product template buttons */
519		initSingleProductTemplateButtons();
520
521		/* Init custom order-review template quantity buttons */
522		initOrderReviewQtyButtons();
523
524		$body.on(
525			'updated_checkout',
526			function() {
527				showHidePlaceOrder();
528
529				/* Init custom order-review template quantity buttons */
530				initOrderReviewQtyButtons();
531
532				/* Check the create account fields are correctly displayed when subscriptions are part of the cart/order after ajax update */
533				create_account_toggle();
534			}
535		);
536
537		function initOrderReviewQtyButtons() {
538
539			$( '#order_review.opc_order_review div.quantity:not(.buttons_added)' ).addClass( 'buttons_added' ).append( '<input type="button" value="+" class="plus" />' ).prepend( '<input type="button" value="-" class="minus" />' );
540		}
541
542		function showHidePlaceOrder() {
543
544			if ( $( '#order_review tbody' ).children().length > 0 ) {
545				/* Stop animations from other plugins and show immediately.*/
546				$( '#place_order' ).stop();
547				$( '#place_order' ).animate( { opacity: 'show', height: 'show', padding: 'show' }, 0 );
548				$( '#payment .payment_methods' ).show();
549			} else {
550				/* Stop animations from other plugins and hide immediately*/
551				$( '#place_order' ).stop();
552				$( '#place_order' ).animate( { opacity: 'hide', height: 'hide', padding: 'hide' }, 0 );
553				$( '#payment .payment_methods' ).hide();
554			}
555		}
556
557		function initSingleProductTemplateButtons() {
558
559			$( '#opc-product-selection button.single_add_to_cart_button' ).each(
560				function() {
561
562					$( this ).after( wcopc.wcopc_complete_order_prompt );
563					$( this ).attr( 'data-add_to_cart', $( this ).closest( '.cart' ).find( '[name="add-to-cart"]' ).val() );
564					$( this ).data( 'add_to_cart', $( this ).closest( '.cart' ).find( '[name="add-to-cart"]' ).val() );
565				}
566			);
567
568		}
569
570		function getUrlsParams( queryString ){
571
572			var match,
573			pl     = /\+/g,  // Regex for replacing addition symbol with a space
574			search = /([^&=]+)=?([^&]*)/g,
575			decode = function (s) { return decodeURIComponent( s.replace( pl, ' ' ) ); };
576
577			urlParams = {};
578
579			while ( match = search.exec( queryString ) ) {
580				urlParams[ decode( match[1] ) ] = decode( match[2] );
581			}
582
583			return urlParams;
584		}
585
586		function create_account_toggle() {
587
588			if ( $( '.opc_order_review' ).length ) {
589
590				var $p_create_account                      = $( 'p.create-account' );
591				var $dif_create_account                    = $( 'div.create-account' );
592				var create_account_p_original_visibility   = $p_create_account.is( ":visible" );
593				var create_account_div_original_visibility = $dif_create_account.is( ":visible" );
594
595				if ( $( '.opc_order_review tfoot .recurring-totals' ).children().length > 0 ) {
596
597					// Hide create account option checkbox container if it was visible
598					if ( create_account_p_original_visibility ) {
599						$p_create_account.hide();
600					}
601
602					// And to be safe ensure the checkbox is checked
603					$( '#createaccount' ).prop( 'checked', true );
604
605					// If the fields weren't visible to begin with lets show them
606					if ( ! create_account_div_original_visibility ) {
607						$dif_create_account.show(); // show div
608					}
609				} else {
610
611					// If visible originally - lets make sure its visible once again
612					if ( 'no' === wc_checkout_params.wcopc_option_guest_checkout ) {
613						$p_create_account.hide();
614						$dif_create_account.show();
615						$( '#createaccount' ).prop( 'checked', true );
616					} else {
617						$p_create_account.show();
618						$dif_create_account.hide();
619						$( '#createaccount' ).prop( 'checked', false );
620					}
621				}
622			}
623		}
624
625	}
626);
627
628/*! jQuery visible 1.1.0 teamdf.com/jquery-plugins | teamdf.com/jquery-plugins/license */
629(function(d){d.fn.visible = function(e,i){var a = d( this ).eq( 0 ),f = a.get( 0 ),c = d( window ),g = c.scrollTop();c = g + c.height();var b = a.offset().top,h = b + a.height();a = e === true ? h : b;b = e === true ? b : h;return ! ! (i === true ? f.offsetWidth * f.offsetHeight : true) && b <= c && a >= g}})( 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.