PageSourceSearch

https://www.exakat.io/wp-content/plugins/woocommerce-one-page-checkout/js/one-page-checkout.js?ver=1.0

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