PageSourceSearch

https://shop.picklebums.com/wp-content/plugins/kadence-shop-kit/li…/assets/frontend/js/main.js?ver=3.0.8

js picklebums.com collected 2026-09-24 10:28:20 UTC 36,127 bytes, 1,065 lines download raw bytes

1
2
3jQuery( function( $ ) {
4	"use strict";
5
6	if ( window?.wc?.blocksCheckout ) {
7		const { registerCheckoutFilters } = wc.blocksCheckout;
8		const { sprintf, __ } = wp.i18n;
9	
10		const modifyItemName = ( defaultValue, extensions, args ) => {
11			if ( ! extensions?.iconic_sales_booster?.added_via_at_checkout_bump ) {
12				return defaultValue;
13			}
14	
15			return sprintf( __( '(Offer) %s', 'kadence-shop-kit' ), defaultValue );
16		};
17	
18		registerCheckoutFilters( 'iconic-sales-booster', {
19			itemName: modifyItemName,
20		} );
21	}
22
23	$( document ).on( 'change', '[data-iconic-wsb-checkout-bump-trigger]', function() {
24		if ( ! $( this ).parents('[data-block-name="woocommerce/checkout"]').length ) {
25			return;
26		}
27
28		if (! wc?.blocksCheckout?.extensionCartUpdate) {
29			return;
30		}
31
32		const $fields = $( this ).siblings('input[type="hidden"]');
33
34		const data = {
35			'bump-type': 'at-checkout',
36			'iconic-wsb-bump-id': $fields.filter('[name="iconic-wsb-bump-id"]').val(),
37			'iconic-wsb-checkout-bump-action': $( this ).prop( 'checked' ) ? 'add' : 'remove',
38			'iconic-wsb-checkout-product-id': $fields.filter('[name="iconic-wsb-checkout-product-id"]').val(),
39			'iconic-wsb-checkout-variation-id': $fields.filter('[name="iconic-wsb-checkout-variation-id"]').val(),
40			'iconic-wsb-checkout-variation-data': $fields.filter('[name="iconic-wsb-checkout-variation-data"]').val(),
41		}
42
43		$( '.wp-block-woocommerce-checkout' ).block( {
44			message: null,
45			overlayCSS: {
46				background: '#fff',
47				opacity: 0.6
48			}
49		} );
50
51		wc.blocksCheckout.extensionCartUpdate( {
52			namespace: 'iconic-sales-booster',
53			data
54		} )
55		.then(() => {
56			checkoutBumpVariableProduct.handleSwatchesLabel();
57			checkoutBumpVariableProduct.handleOverlay();
58			checkoutBumpVariableProduct.handleCheckbox();
59
60			$( '.wp-block-woocommerce-checkout' ).unblock();
61		});
62
63	});
64
65	wp.data.subscribe(
66		() => {
67			if ( ! wp.data.select('wc/store/checkout')?.isBeforeProcessing() ) {
68				return;
69			}
70
71			if ( ! $('[data-iconic-wsb-acb-modal]').length ) {
72				return;
73			}
74
75			wp.data.dispatch('wc/store/checkout').__internalSetIdle();
76
77			$.magnificPopup.open({items: {
78				type: 'inline',
79				src: $('[data-iconic-wsb-acb-modal]')
80			}})
81			
82		},
83		'wc/store/checkout'
84	);
85
86	$( '[data-iconic-wsb-acb-add-to-cart-button]' ).on(
87		'click',
88		function( event ) {
89			if ( ! window?.wc?.blocksCheckout ) {
90				return;
91			}
92
93			event.preventDefault();
94
95			const $fields = $( '.iconic-wsb-acb-fields input[type="hidden"]' );
96
97			const data = {
98				'bump-type': 'after-checkout',
99				'iconic-wsb-acb-action': 'add',
100				'iconic-wsb-acb-bump-id': $fields.filter('[name="iconic-wsb-acb-bump-id"]').val(),
101				'iconic-wsb-acb-variation-id': $fields.filter('[name="iconic-wsb-acb-variation-id"]').val(),
102				'iconic-wsb-acb-variation-data': $fields.filter('[name="iconic-wsb-acb-variation-data"]').val(),
103			}
104
105			wc.blocksCheckout
106				.extensionCartUpdate(
107					{
108						namespace: 'iconic-sales-booster',
109						data
110					}
111				)
112				.then(() => {
113					$.magnificPopup.close();
114					$('[data-iconic-wsb-acb-modal]').remove();
115					wp.data.dispatch('wc/store/checkout').__internalSetBeforeProcessing();
116				});
117		}
118	);
119
120	$( '[data-iconic-wsb-acb-close-button]' ).on(
121		'click',
122		function( event ) {
123			if ( ! window?.wc?.blocksCheckout ) {
124				return;
125			}
126
127			event.preventDefault();
128			$.magnificPopup.close();
129			$('[data-iconic-wsb-acb-modal]').remove();
130			wp.data.dispatch('wc/store/checkout')?.__internalSetBeforeProcessing();
131		}
132	);
133
134	/**
135	 * Trigger add offered product to order
136	 */
137	$( document ).on( 'change', '[data-iconic-wsb-checkout-bump-trigger]', function() {
138		var actionTypeInput = $( '[name=iconic-wsb-checkout-bump-action]' );
139		var bumpInForm = true;
140		var bumpWrapper = $(this).closest( '.iconic-wsb-checkout-bump' );
141
142		// If the hook is outside of the form, make sure it still works.
143		if ( ! $(this).closest('form.checkout').length ) {
144			bumpInForm = false;
145		}
146
147		if ( ! $( this ).prop( 'checked' ) ) {
148			actionTypeInput.val( 'remove' );
149		} else {
150			actionTypeInput.val( 'add' );
151
152			if ( ! bumpInForm ) {
153				bumpWrapper.find( 'input[name="iconic-wsb-bump-id"]' ).clone().appendTo( 'form.checkout' );
154				bumpWrapper.find( 'input[name="iconic-wsb-checkout-bump-action"]' ).clone().appendTo( 'form.checkout' );
155				bumpWrapper.find( 'input[name="iconic-wsb-checkout-product-id"]' ).clone().appendTo( 'form.checkout' );
156				bumpWrapper.find( 'input[name="iconic-wsb-checkout-variation-id"]' ).clone().appendTo( 'form.checkout' );
157				bumpWrapper.find( 'input[name="iconic-wsb-checkout-variation-data"]' ).clone().appendTo( 'form.checkout' );
158			}
159		}
160
161		$( 'body' ).trigger( 'update_checkout' );
162
163		// If we are removing, we need to wait for the form to finish posting.
164		if ( ! $( this ).prop( 'checked' ) && ! bumpInForm ) {
165			setTimeout( function() {
166				$( 'form.checkout input[name="iconic-wsb-bump-id"]' ).remove();
167				$( 'form.checkout input[name="iconic-wsb-checkout-bump-action"]' ).remove();
168				$( 'form.checkout input[name="iconic-wsb-checkout-product-id"]' ).remove();
169				$( 'form.checkout input[name="iconic-wsb-checkout-variation-id"]' ).remove();
170				$( 'form.checkout input[name="iconic-wsb-checkout-variation-data"]' ).remove();
171			}, 500 );
172		}
173	} );
174
175	/**
176	 * After checkout bump
177	 * @constructor
178	 */
179	var AfterCheckoutBump = function() {
180		this.isBumpShowed = false;
181		this.isFormSubmited = false;
182
183		this.init = function() {
184			this.$checkoutForm       = $( 'form.checkout' );
185			this.container           = '[data-iconic-wsb-acb-modal]';
186			this.$bumpModal          = $( this.container );
187			this.$addToCartButton    = $( '[data-iconic-wsb-acb-add-to-cart-button]' );
188			this.$closeButton        = $( '[data-iconic-wsb-acb-close-button]' );
189			this.actionInputSelector = '[name=iconic-wsb-acb-action]';
190			this.$form               = $( '.iconic-wsb-after-checkout-bump-form' );
191			this.variation_dropdown  = ".iconic-wsb-checkout-modal__select";
192			this.variationHandler    = new IconicVariationHandler(this.$form, this.container, this.onVariationFound.bind( this ) , this.onVariationNotFound.bind( this ) );
193			var self                 = this;
194
195			// If suitable order bump exists
196			if ( this.$bumpModal.length > 0 ) {
197
198				this.$checkoutForm.on( 'checkout_place_order.orderBump', this.openModal.bind( this ) );
199				this.$closeButton.on( 'click', this.close.bind( this ) );
200
201				this.$addToCartButton.on( 'click', (function( e ) {
202					e.preventDefault();
203					this.addToCartBump();
204				}).bind( this ) );
205
206				$(this.container).on("change", this.variation_dropdown, this.variationHandler.getVariation.bind( this.variationHandler ) );
207				$( '.wsb_select_readonly option:not(:selected)' ).prop( 'disabled', true );
208
209			}
210
211			//to make compatible with WooCommerce Attribute Swatches plugin
212			this.$form.addClass("variations_form");
213			this.$form.data("product_variations", false);
214		};
215
216		this.close = function() {
217			$.magnificPopup.close();
218			this.$checkoutForm.submit();
219		};
220
221		this.addToCartBump = function() {
222			$( this.actionInputSelector ).val( 'add' );
223
224			this.$checkoutForm.trigger( 'update_checkout' );
225
226			this.$checkoutForm.off( 'checkout_place_order.orderBump', this.openModal.bind( this ) );
227
228			$( document ).ajaxComplete( ( function ( event, xhr, settings ) {
229				
230				// ensure this is the update_order_review AJAX request.
231				if ( ! settings.url.includes( "update_order_review" ) ) {
232					return;
233				}
234
235				if ( this.isFormSubmited === true ) {
236					return;
237				}
238
239				this.isFormSubmited = true;
240
241				this.$checkoutForm.submit();
242			}).bind( this ) );
243
244			$.magnificPopup.close();
245		};
246
247		this.openModal = function() {
248			// Check if we have the modal element.
249			if ( ! $( this.container ).length ) {
250				return;
251			}
252
253			if ( this.isBumpShowed === true ) {
254				return true;
255			}
256
257			this.variationHandler.getVariation();
258
259			var modalConfig = {
260				items: {
261					src: this.$bumpModal,
262					type: 'inline',
263				}
264			};
265
266			modalConfig = Object.assign(
267				modalConfig,
268				Object( iconic_wsb_frontend_vars && iconic_wsb_frontend_vars.modal_options ) 
269			);
270
271			$.magnificPopup.open(modalConfig);
272
273			this.isBumpShowed = true;
274
275			return false;
276		};
277
278		this.onVariationFound = function( variation ) {
279			this.$addToCartButton.attr( "disabled", false );
280			this.$form.find(".iconic-wsb-checkout-modal-unavailable_msg").hide();
281			this.$form.find(".iconic-wsb-modal-product-offer__price").html( variation.price_html );
282			$("[name='iconic-wsb-acb-variation-id']").val( variation.variation_id );
283		};
284
285		this.onVariationNotFound = function() {
286			this.$addToCartButton.attr( "disabled", true );
287			this.$form.find( ".iconic-wsb-checkout-modal-unavailable_msg" ).slideDown( 200 );
288			this.$form.find(".iconic-wsb-modal-product-offer__price").html("");
289			$("[name='iconic-wsb-acb-variation-id']").val( "" );
290		};
291	};
292
293	var CheckoutBumpVariableProduct = function() {
294
295		this.allVariationSelectedFlag = null;
296		this.$attributeFields         = null;
297		this.$woocommerceWrapper      = $( '.page.woocommerce-checkout, [data-block-name="woocommerce/checkout"]' );
298		this.container                = ".iconic-wsb-checkout-bump";
299		this.variation_dropdown       = ".iconic-wsb-checkout-bump__select";
300
301		/**
302		 * Initialize
303		 */
304		this.init = function () {
305			var self = this;
306			self.variationHandler = new IconicVariationHandler(self.$woocommerceWrapper, this.container, this.onVariationFound.bind( self ), this.onVariationNotFound.bind( self ) );
307
308			$(self.$woocommerceWrapper).on("change", this.variation_dropdown, this.variationHandler.getVariation.bind( this.variationHandler ) );
309			$(self.$woocommerceWrapper).on("change", this.variation_dropdown, this.handleCheckbox.bind(this) );
310
311			self.product_type = self.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump" ).data( "product_type" );
312
313			if( self.product_type === "variable" ) {
314
315				if ( self.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump__select" ).length ) {
316					self.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump__header-checkbox" ).attr( "disabled", !self.variationHandler.checkAllSelects.bind( self.variationHandler ) );
317				}
318
319				self.handleSwatchesLabel();
320				self.handleOverlay();
321				self.handleCheckbox();
322			}
323
324			$( document.body ).on( 'updated_checkout', function() {
325
326				self.product_type = self.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump" ).data( "product_type" );
327
328				if( self.product_type === "variable" ) {
329
330					if ( self.$woocommerceWrapper.find( "[name=iconic-wsb-checkout-variation-id]" ).length && $( "[name=iconic-wsb-checkout-variation-id]" ).val() === '' ) {
331						self.variationHandler.getVariation( false ); //need to run getVariation after updated_checkout has been triggered
332					}
333
334					if ( self.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump__select" ).length ) {
335						self.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump__header-checkbox" ).attr( "disabled", !self.variationHandler.checkAllSelects.bind( self.variationHandler ) );
336					}
337
338					self.handleSwatchesLabel();
339					self.handleOverlay();
340					self.handleCheckbox();
341				}
342				
343				$('.wsb_select_readonly option:not(:selected)').prop('disabled', true);
344			});
345			
346			//to make compatible with WooCommerce Attribute Swatches plugin
347			this.$woocommerceWrapper.addClass( "variations_form" );
348			this.$woocommerceWrapper.data( "product_variations" , false );
349
350			// handle order bump outside of form.checkout
351			if ( ! $('form.checkout .iconic-wsb-checkout-bump').length ) {
352				if ( $('.iconic-wsb-checkout-bump__header-checkbox').prop('checked') ) {
353					this.$woocommerceWrapper.find( 'input[name="iconic-wsb-bump-id"]' ).clone().appendTo( 'form.checkout' );
354					this.$woocommerceWrapper.find( 'input[name="iconic-wsb-checkout-bump-action"]' ).clone().appendTo( 'form.checkout' );
355					this.$woocommerceWrapper.find( 'input[name="iconic-wsb-checkout-product-id"]' ).clone().appendTo( 'form.checkout' );
356					this.$woocommerceWrapper.find( 'input[name="iconic-wsb-checkout-variation-id"]' ).clone().appendTo( 'form.checkout' );
357					this.$woocommerceWrapper.find( 'input[name="iconic-wsb-checkout-variation-data"]' ).clone().appendTo( 'form.checkout' );
358				}
359			}
360			
361			setTimeout(() => {
362				/**
363				 * Set the value of the `data-value` attribute to the `value` attribute.
364				 *
365				 * When using the Checkou block, the `value` attribute is removed so
366				 * we re-add by copying the data from `data-value`.
367				 */
368				$('.iconic-wsb-variation__select.iconic-wsb-checkout-bump__select option').each(function() {
369					$( this ).attr( 'value', $( this ).attr('data-value') || '' );
370				});
371			}, 700);
372		};
373
374
375		/**
376		 * 1)Hides unavailable variation message 2) Enables the 'Add to cart' checkbox
377		 */
378		this.onVariationFound = function (variation) {
379			this.$woocommerceWrapper.find("[data-iconic-wsb-checkout-bump-trigger]").attr("disabled", false);
380			this.$woocommerceWrapper.find(".iconic-wsb-checkou-bump_unavailable_msg").hide();
381		};
382
383		/**
384		 * 1)Shows unavailable variation message 2) Disables the 'Add to cart' checkbox
385		 */
386		this.onVariationNotFound = function() {
387			this.$woocommerceWrapper.find("[data-iconic-wsb-checkout-bump-trigger]").attr("disabled", true);
388			this.$woocommerceWrapper.find(".iconic-wsb-checkou-bump_unavailable_msg").slideDown(200);
389			
390		};
391
392		/**
393		 * Show/Hide overlay to prevent user from changing the variation after the product has been added to cart.
394		 */
395		this.handleOverlay = function() {
396			var isInCart = this.$woocommerceWrapper.find( "[data-iconic-wsb-checkout-bump-trigger]" ).prop( "checked" );
397			if ( isInCart ) {
398				this.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump" ).addClass( "iconic-wsb-checkout-bump__overlay_active" );
399				this.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump__overlay" ).show();
400			}
401			else {
402				this.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump" ).removeClass("iconic-wsb-checkout-bump__overlay_active");
403				this.$woocommerceWrapper.find( ".iconic-wsb-checkout-bump__overlay" ).hide();
404			}
405		};
406
407		/**
408		 * If Woocomerce Attributes Swatches plugin is enabled then makes sure that lables for attributes are visible
409		 */
410		this.handleSwatchesLabel = function() {
411			if( this.$woocommerceWrapper.find(".iconic-was-swatches").length ) {
412				this.$woocommerceWrapper.find(".iconic-wsb-variation__select").each(function () {
413					var val = jQuery(this).val();
414					if ( val ) {
415						var $row = jQuery( this ).closest( "tr" );
416						var html = $row.find( "td.label label .iconic-was-chosen-attribute" ).html();
417						if ( html && html.trim() === "" ) {
418							var new_html = $row.find( ".iconic-was-swatch--selected" ).data( "attribute-value-name" );
419							$row.find( "td.label label .iconic-was-chosen-attribute" ).html( new_html );
420						}
421					}
422				});
423			}
424		};
425
426		/**
427		 * Enable or disable 'data-iconic-wsb-checkout-bump-trigger' checkbox
428		 */
429		this.handleCheckbox = function() {
430			var $checkbox = this.$woocommerceWrapper.find("[data-iconic-wsb-checkout-bump-trigger]");
431			//1) If: $checkbox is checked then user should be able to uncheck it, hence always enable it. Else: if any of the attributes are not selected, then disable $checkox
432			if ( $checkbox.prop("checked") ) {
433				$checkbox.attr( "disabled" , false );
434			}
435			else {
436				this.$woocommerceWrapper.find( "[data-iconic-wsb-checkout-bump-trigger]" ).attr( "disabled", ! this.variationHandler.checkAllSelects() );
437			}
438		};
439
440	};
441
442	var afterCheckoutBump = new AfterCheckoutBump();
443	var checkoutBumpVariableProduct = new CheckoutBumpVariableProduct();
444
445	/**
446	 * Clear After Add to Cart fragments on Checkout page.
447	 *
448	 * @returns void
449	 */
450	function clear_after_add_to_cart_fragment_on_checkout_page() {
451		if ( ! iconic_wsb_frontend_vars?.is_checkout ) {
452			return;
453		}
454
455		const fragment_name = wc_cart_fragments_params?.fragment_name;
456
457		if ( ! fragment_name || 'string' !== typeof fragment_name ) {
458			return;
459		}
460
461		let fragments = sessionStorage.getItem( fragment_name );
462
463		if ( ! fragments ) {
464			return;
465		}
466
467		fragments = JSON.parse( fragments );
468
469		fragments['.iconic_wsb_after_add_to_cart_popup_placeholder'] = undefined;
470
471		sessionStorage.setItem(
472			wc_cart_fragments_params.fragment_name,
473			JSON.stringify( fragments )
474		);
475	}
476
477	$( document ).ready( function() {
478		checkoutBumpVariableProduct.init();
479		afterCheckoutBump.init();
480
481		clear_after_add_to_cart_fragment_on_checkout_page();
482
483		if ( $( '[data-block-name="woocommerce/checkout"]' ).length ) {
484			return;
485		}
486
487		$( document ).on( 'updated_checkout', function( event, data ) {
488			if ( ! data.fragments || ! data.fragments['.iconic-wsb-modal'] ) {
489				return;
490			}
491
492			var refreshedAfterCheckoutBump = new AfterCheckoutBump();
493			
494			refreshedAfterCheckoutBump.init();
495		})
496	} );
497
498} );
499
500jQuery( function( $ ) {
501	"use strict";
502
503	/**
504	 * After add to cart bump
505	 * @constructor
506	 */
507	var AfterAddToCartBump = function() {
508		this.init = function() {
509			this.$bumpModal = $( '[data-iconic-wsb-acc-modal-bump]' );
510			this.$closeButton = $( '[data-iconic-wsb-close-aac-modal]' );
511			this.$variation_wrap = jQuery( this.$bumpModal.selector + ' .single_variation_wrap' );
512
513			// If order bump modal exists
514			if ( this.$bumpModal.length > 0 ) {
515
516				this.$closeButton.on( 'click', this.close.bind( this ) );
517				this.$variation_wrap.on( 'show_variation', this.changeVariationImage );
518
519				this.openModal();
520			}
521		};
522
523		this.changeVariationImage = function( event, variation ) {
524			if ( variation.image.thumb_src !== undefined ) {
525				var $image = $( this ).closest( '[data-iconic-wsb-acc-modal-bump-offer-product]' ).find( '[data-iconic-wsb-acc-modal-bamp-offer-image]' ).find( 'img' );
526				$image.attr( 'srcset', '' );
527				$image.attr( 'src', variation.image.thumb_src );
528			}
529		};
530
531		this.close = function() {
532			$.magnificPopup.close();
533			$( '[data-iconic-wsb-acc-modal-bump]' ).remove();
534		};
535
536		this.openModal = function() {
537			var modalConfig = {
538				items: {
539					src: this.$bumpModal,
540					type: 'inline',
541				}
542			};
543
544			modalConfig = Object.assign(
545				modalConfig,
546				Object( iconic_wsb_frontend_vars && iconic_wsb_frontend_vars.modal_options )
547			);
548
549			$.magnificPopup.open(modalConfig);
550			$('[data-iconic-wsb-acc-modal-bump]').fadeIn(100);
551		};
552	};
553
554	/**
555	 * Handles all the events and actions for FBT module
556	 */
557	var FrequentlyBoughTogether = function() {
558
559		this.init = function() {
560			$( '.variations_form' ).on( 'found_variation', this.variationChangeHandle.bind( this ) );
561
562			$( '.iconic-wsb-bump-product__select' ).change( function( e ) {
563				this.toggleButtonStatus.bind( this )();
564				this.updateTotalPrice.bind( this )();
565				this.fetchVariationPrice.bind( e.target )();
566				this.updateAttributeData.bind( e.target )();
567			}.bind( this ) );
568
569			$( '.iconic-wsb-bump-product__checkbox' ).change( function() {
570				this.updateTotalPrice();
571				this.toggleButtonStatus();
572			}.bind( this ) );
573
574			this.toggleButtonStatus();
575			this.addToCartAjax();
576			this.toggleProductImages();
577			this.disableFormSubmitForDisabledButton();
578		};
579
580		/**
581		 * Saves the attribute's data as JSON in hidden fields. Is called when FBT dropdown is changed.
582		 */
583		this.updateAttributeData = function() {
584			var product_id = $( this ).data( "product_id" ),
585				attributes = $( this ).find( "option:selected" ).data( "attributes" ),
586				attributes_str = typeof attributes === 'object' ? JSON.stringify( attributes ) : attributes;
587
588			$( "[name='iconic-wsb-bump-product_attributes-" + product_id + "']" ).val( attributes_str );
589		};
590
591		/**
592		 * Disable "Add Selected to Cart" button when
593		 * either variation is not selected for any variable products
594		 * or no products are checked
595		 */
596		this.toggleButtonStatus = function() {
597			// Check if variations are selected
598			var variableSelectFlag = true;
599			$( '.iconic-wsb-product-bumps__list-item' ).each( function() {
600				if ( $( this ).find( ".iconic-wsb-bump-product__checkbox" ).prop( "checked" ) ) {
601					var $select = $( this ).find( ".iconic-wsb-bump-product__select" );
602					if ( $select.length && ! $select.val() ) {
603						variableSelectFlag = false;
604					}
605				}
606			} );
607
608			// check if atleast one product is checked
609			var selectedProductsCount = $( '.iconic-wsb-bump-product__checkbox:checked' ).length;
610
611			if ( variableSelectFlag && selectedProductsCount ) {
612				$( ".iconic-wsb-product-bumps__button" ).removeClass( "disabled" );
613			} else {
614				$( ".iconic-wsb-product-bumps__button" ).addClass( "disabled" );
615			}
616		};
617
618		/**
619		 * Disable form submit when the button is disabled ( variations needs to be selected )
620		 */
621		this.disableFormSubmitForDisabledButton = function() {
622
623			/**
624			 * As we have multiple submit buttons on the form. Here we are saving
625			 * the button which was clicked. This data will be used in form submit event.
626			 */
627			$( 'form.cart' ).click( function( e ) {
628				$(this).data( 'clicked', $( e.target ) );
629			});
630
631			$( 'form.cart' ).submit( function( e ) {
632				// Only prevent form submit when clicked on "Add selected to cart" button.
633				if( $(this).data('clicked').is( "[data-bump-product-form-submit]" ) ) {
634					if( $(this).find( '.iconic-wsb-product-bumps__button' ).hasClass( "disabled" ) ) {
635						e.preventDefault();
636						return false;
637					}
638				}
639			} );
640
641			$( '.iconic-wsb-product-bumps__button' ).click( function() {
642				if( $( this ).hasClass( "disabled" ) ) {
643					alert( iconic_wsb_frontend_vars.i18n.disabled_add_to_cart );
644				}
645			} );
646		};
647
648		/**
649		 * Fetch price for the selected variation
650		 */
651		this.fetchVariationPrice = function() {
652
653			var data = {
654				action: 'iconic_wsb_get_variation_price',
655				variation_id: jQuery( this ).val(),
656				_ajax_nonce: iconic_wsb_frontend_vars.nonce
657			};
658
659			var self = this;
660
661			const selector = $( '.variations_form' ).length ? '.variations_form' : '.iconic-wsb-product-bumps';
662
663			$( selector ).block( { message: null, overlayCSS: { background: '#fff', opacity: 0.6 } } );
664
665			jQuery.post( iconic_wsb_frontend_vars.ajax_url, data, function( response ) {
666				$( selector ).unblock();
667
668				if ( !response.success ) {
669					return;
670				}
671
672				jQuery( self ).siblings( ".iconic-wsb-bump-product__price" ).html( response.data.variation_price_html );
673			} );
674
675		};
676
677		/**
678		 * Fetches and shows the total price of selected products
679		 */
680		this.updateTotalPrice = function() {
681			var product_ids = [];
682
683			//collect all product IDs in product_ids
684			$( ".iconic-wsb-product-bumps__list-item" ).each( function() {
685				if ( $( this ).find( ".iconic-wsb-bump-product__checkbox" ).is( ":checked" ) ) {
686					if ( $( this ).data( "product_type" ) === "variable" ) {
687						var parent_id = parseInt( $( this ).data( "product_id" ) ),
688							variation_value = parseInt( $( this ).find( ".iconic-wsb-bump-product__select" ).val() ),
689							id = variation_value > 0 ? variation_value : parent_id;
690
691						product_ids.push( id );
692					} else {
693						product_ids.push( $( this ).data( "product_id" ) );
694					}
695				}
696			} );
697
698			var data = {
699				action: 'iconic_wsb_fbt_get_products_price',
700				product_ids: product_ids,
701				offer_product_id: $( "[name='iconic-wsb-fbt-this-product']" ).val(),
702				_ajax_nonce: iconic_wsb_frontend_vars.nonce
703			};
704
705			var $variation_form = $( '.iconic-wsb-product-bumps' ).parents( '.variations_form' );
706
707			$variation_form.block( { message: null, overlayCSS: { background: '#fff', opacity: 0.6 } } );
708
709			$.post( iconic_wsb_frontend_vars.ajax_url, data, function( data ) {
710				$( ".iconic-wsb-product-bumps__total-price-amount" ).html( data.html );
711				$variation_form.unblock();
712			} );
713
714		};
715
716		/**
717		 * Responsible for selecting the right option from the Dropdown under
718		 * "Add Selected to Cart" when user changes attributes.
719		 */
720		this.variationChangeHandle = function( e, variation_data ) {
721			this.variationId = variation_data.variation_id;
722			this.currentProductId = $( "form.cart" ).data( "product_id" );
723			if ( this.variationId && $( ".iconic-wsb-bump-product__select--" + this.currentProductId ).length ) {
724				var $select = $( ".iconic-wsb-bump-product__select--" + this.currentProductId );
725
726				//gather all the Single product attributes in `currentProductAttributes`
727				var currentProductAttributes = {};
728				$( "form.cart .variations select" ).each( function() {
729					currentProductAttributes[ $( this ).data( "attribute_name" ) ] = $( this ).find( "option:selected" ).text();
730				} );
731
732				//find the matching 'option in the dropdown'
733				var matchIndex = 0;
734				$( ".iconic-wsb-bump-product__select--" + this.currentProductId + " option" ).each( function( optionIndex ) {
735					var $option = $( this );
736					var optionAttribute = $option.data( "attributes" );
737					var matchFlag = true;
738					var attribute;
739					for ( attribute in currentProductAttributes ) {
740						if ( optionAttribute && optionAttribute[ attribute ]['label'] === currentProductAttributes[ attribute ] ) {
741							//ok
742						} else {
743							matchFlag = false;
744						}
745					}
746					if ( matchFlag ) {
747						matchIndex = optionIndex;
748						$select.find( "option" ).eq( matchIndex ).prop( 'selected', true );
749						$select.change();
750					}
751				} );
752			}
753		};
754
755		/**
756		 * Adds products to the cart with AJAX rather than page reload, when AJAX setting is enabled
757		 */
758		this.addToCartAjax = function() {
759			$( document.body ).on( 'click', '[data-bump-product-form-submit]', function( e ) {
760				var $button = $( this );
761
762				if ( $button.prop( 'disabled' ) || $button.hasClass( 'disabled' ) || '1' !== iconic_wsb_frontend_vars.fbt_use_ajax ) {
763					return;
764				}
765
766				var $bumps = $button.closest( '.iconic-wsb-product-bumps' ),
767					$form = $button.closest( 'form.cart' ),
768					bumpInForm = true,
769					$product_id = $button.data( 'product-id' );
770
771				// If the bump is not within the form.
772				if ( ! $form.length ) {
773					bumpInForm = false;
774					$form = $( 'form.cart' );
775
776					// If form is not on a product page.
777					if ( ! $form.length ) {
778						$form = $( document.createElement( 'form' ) );
779						$( '.iconic-wsb-product-bumps' ).clone().appendTo( $form );
780					} else {
781						// Copy the hidden field to the form.
782						$bumps.find( 'input[name="iconic-wsb-fbt-this-product"]' ).clone().appendTo( 'form.cart' );
783
784						// Loop checked items and add those as hidden fields to the form.
785						$bumps.find( '.iconic-wsb-bump-product__checkbox:checked' ).each( function() {
786							var element = $( document.createElement( 'input' ) );
787							element.attr( 'type', 'hidden' );
788							element.attr( 'name', $( this ).attr( 'name') );
789							element.val( $( this ).val() );
790							element.attr( 'class', $( this ).attr( 'class') );
791							element.appendTo( $form );
792
793							var select = $( this ).closest( 'label' ).find( 'select[name^="iconic-wsb-products-add-to-cart-variation-"]' );
794							if ( select.length ) {
795								var element = $( document.createElement( 'input' ) );
796								element.attr( 'type', 'hidden' );
797								element.attr( 'name', select.attr( 'name') );
798								element.attr( 'class', select.attr( 'class') );
799								element.val( select.val() );
800								element.data( select.data() );
801								element.appendTo( $form );
802							} else {
803								$( this ).closest( 'label' ).find( 'input[name^="iconic-wsb-products-add-to-cart-variation-"]').clone().appendTo( $form );
804							}
805
806							$( this ).closest( 'label' ).find( 'input[name^="iconic-wsb-bump-product_attributes-"]').clone().appendTo( $form );
807						});
808					}
809				}
810
811				e.preventDefault();
812
813				$bumps.block( { message: null, overlayCSS: { background: '#fff', opacity: 0.6 } } );
814				$button.prop( "disabled", true );
815
816				// Clear messages.
817				$( '.woocommerce-notices-wrapper' ).html( '' );
818
819				$.ajax( {
820					type: 'POST',
821					url: wc_add_to_cart_params.ajax_url,
822					data: $form.serialize() + "&iconic-wsb-add-selected=1&action=iconic_wsb_fbt_add_to_cart&post_id=" + $product_id,
823					success: function( result ) {
824						$button.text( iconic_wsb_frontend_vars.i18n.success );
825
826						// Show notice.
827						var notice_class = result.success ? 'woocommerce-message' : 'woocommerce-error';
828						$( '.woocommerce-notices-wrapper' ).append( '<div class="' + notice_class + '">' + result.message + '</div>'  );
829						jQuery.scroll_to_notices( $(".woocommerce-notices-wrapper") );
830						$bumps.unblock();
831
832						// Redirect to cart if set in Woocommerce settings.
833						if ( wc_add_to_cart_params.cart_redirect_after_add === "yes" ) {
834							window.location = wc_add_to_cart_params.cart_url;
835						} else {
836							$( document.body ).trigger( 'added_to_cart', [result.fragments, result.cart_hash] );
837						}
838					},
839					error: function() {
840						$button.text( iconic_wsb_frontend_vars.i18n.error );
841						$bumps.unblock();
842					},
843					complete: function() {
844						setTimeout( function() {
845							$button.prop( "disabled", false ).text( iconic_wsb_frontend_vars.i18n.add_selected );
846
847							// If the bump was not in the form, clean it up.
848							if ( ! bumpInForm ) {
849								$( 'form.cart input[name="iconic-wsb-fbt-this-product"]' ).remove();
850								$( 'form.cart .iconic-wsb-bump-product__checkbox' ).remove();
851								$( 'form.cart input[name^="iconic-wsb-bump-product_attributes-"]').remove();
852								$( 'form.cart select[name^="iconic-wsb-products-add-to-cart-variation-"]').remove();
853							}
854						}, 3000 );
855					}
856				} );
857			} );
858		};
859
860		/**
861		 * Toggle the related thumbnail when checkbox for a product is deselected.
862		 */
863		this.toggleProductImages = function() {
864			$( '.iconic-wsb-bump-product__checkbox' ).change( function() {
865				var $checkbox = $( this ),
866					$list_item = $checkbox.closest( '.iconic-wsb-product-bumps__list-item' ),
867					$bumps = $checkbox.closest( '.iconic-wsb-product-bumps' ),
868					id = $checkbox.val(),
869					$images_wrapper = $( '.iconic-wsb-product-bumps__images' ),
870					$images = $( '.iconic-wsb-product-bumps__image' );
871
872				if ( !$checkbox.is( ':checked' ) ) {
873					$list_item.addClass( 'iconic-wsb-product-bumps__list-item--faded' );
874					$( '.iconic-wsb-product-bumps__image[data-product-id=' + id + ']' ).hide();
875				} else {
876					$list_item.removeClass( 'iconic-wsb-product-bumps__list-item--faded' );
877					$( '.iconic-wsb-product-bumps__image[data-product-id=' + id + ']' ).show();
878				}
879
880				// Remove plus on last visible item.
881				var $last_visible = $bumps.find( '.iconic-wsb-product-bumps__image:visible:last' );
882
883				$images.removeClass( 'iconic-wsb-product-bumps__image--no-plus' );
884				$last_visible.addClass( 'iconic-wsb-product-bumps__image--no-plus' );
885
886				// Hide section if no images visible.
887				var toggle_images = ! $images_wrapper.is( ':visible' ) || 0 < $last_visible.length;
888				$images_wrapper.toggle( toggle_images );
889			} );
890
891			$( '.iconic-wsb-bump-product__checkbox' ).trigger('change')
892		};
893	};
894
895	var afterAddToCartBump = new AfterAddToCartBump();
896	var frequentlyBoughTogether = new FrequentlyBoughTogether();
897
898	$( document ).ready( function() {
899		afterAddToCartBump.init();
900		frequentlyBoughTogether.init();
901	} );
902
903	$( document ).on('added_to_cart', function( e, fragments ) {
904		if (
905			! fragments ||
906			! window.wc_cart_fragments_params ||
907			! wc_cart_fragments_params.fragment_name
908		) {
909			return;
910		}
911
912		afterAddToCartBump.init();
913
914		// Delete from fragments
915		fragments['.iconic_wsb_after_add_to_cart_popup_placeholder'] = undefined;
916		fragments['.woocommerce-notices-wrapper'] = undefined;
917
918		sessionStorage.setItem(
919			wc_cart_fragments_params.fragment_name,
920			JSON.stringify( fragments )
921		);
922	});
923} );
924
925"use strict";
926
927/**
928 * Reusable utility to handles the dropdown changes for the variation dropdowns.
929 * 1. Fetches the variation price when all dropdowns are selected
930 * 2. Saves attributes data in hidden fields 'iconic-wsb-acb-variation-data' or 'iconic-wsb-checkout-variation-data'
931 * 3. Shows and Hides spinner while AJAX
932 *
933 * @param {Object}   form The jQuery instance of the form where variation dropdowns reside
934 * @param {str}      container_selector selector string for the containing div
935 * @param {Function} onVariationFound callback function to be called when the variation is purchasable
936 * @param {Function} onVariationNotFound callback function to be called when the variation is not purchasable
937 */
938var IconicVariationHandler = function (form, container_selector, onVariationFound, onVariationNotFound ) {
939	this.$form              = form;
940	this.container_selector = container_selector;
941
942	this.getVariation = function() {
943		var self = this,
944			$variationIdField = self.$form.find( ".iconic-wsb__variation_id" );
945
946		if ( $variationIdField.length <= 0 ) {
947			return;
948		}
949
950		if ( self.checkAllSelects() ) {
951			
952			self.$attributeFields = jQuery( self.container_selector ).find( '.iconic-wsb-variation__select' );
953			var attributes = self.getChosenAttributes();
954			var currentAttributes = attributes.data;
955			//TODO: Make this more generic. 
956			if ( self.$form.hasClass("iconic-wsb-after-checkout-bump-form") ) {
957				jQuery("[name='iconic-wsb-acb-variation-data']").val(JSON.stringify(currentAttributes));
958			}
959			else {
960				jQuery("[name='iconic-wsb-checkout-variation-data']").val(JSON.stringify(currentAttributes));
961			}
962			currentAttributes.product_id = parseInt( jQuery( self.container_selector ).find( ".iconic-wsb__product_id" ).val() );
963			currentAttributes.action = "iconic_wsb_checkout_get_variation";
964			currentAttributes.bump_id = jQuery( self.container_selector ).find( ".iconic-wsb__bump_id" ).val();
965			currentAttributes._ajax_nonce = iconic_wsb_frontend_vars.nonce;
966			self.showLoader();
967			self.xhr = jQuery.ajax( {
968				url: iconic_wsb_frontend_vars.ajax_url,
969				type: 'POST',
970				data: currentAttributes,
971				success: function( variation ) {
972					if ( variation ) {
973						self.$form.find( "#iconic-wsb-checkout-bump-variation" ).val( variation.variation_id );
974						self.$form.find( ".iconic-wsb-checkout-bump__price_span" ).html( variation.price_html );
975						if ( !variation.is_purchasable || !variation.is_in_stock || !variation.variation_is_visible ) {
976							onVariationNotFound();
977							$variationIdField.val( "" );
978						} else {
979							onVariationFound( variation );
980							$variationIdField.val( variation.variation_id );
981						}
982					} else {
983						onVariationNotFound();
984						$variationIdField.val( "" );
985					}
986					self.hideLoader();
987				},
988				complete: function() {
989					self.hideLoader();
990				}
991			} );
992
993			self.$form.find( "[data-iconic-wsb-acb-add-to-cart-button] , [data-iconic-wsb-checkout-bump-trigger]" ).attr( "disabled", false );
994		} else {
995			self.$form.find( "[data-iconic-wsb-acb-add-to-cart-button], [data-iconic-wsb-checkout-bump-trigger]" ).attr( "disabled", true );
996		}
997	};
998
999	/**
1000	 * Checks all the variation dropdowns.
1001	 * @returns boolean. Returns true iff all attribute dropdowns have a selected value. Returns false even is a single attribute dropdown doesnt has a value.
1002	 */
1003	this.checkAllSelects = function() {
1004		var self = this;
1005		self.allVariationSelectedFlag = true;
1006		jQuery( self.container_selector ).find( ".iconic-wsb-variation__select" ).each( function() {
1007			if ( jQuery( this ).val() ) {
1008				jQuery( this ).closest( "tr" ).removeClass( "iconic-wsb-variation-tr-valdation-error" );
1009			} else {
1010				self.allVariationSelectedFlag = false;
1011				jQuery( this ).closest( "tr" ).addClass( "iconic-wsb-variation-tr-valdation-error" );
1012			}
1013		} );
1014		return self.allVariationSelectedFlag;
1015	};
1016
1017	/**
1018	 * Get chosen attributes from form.
1019	 * @return array
1020	 */
1021	this.getChosenAttributes = function() {
1022		var data = {};
1023		var count = 0;
1024		var chosen = 0;
1025
1026		this.$attributeFields.each( function() {
1027			var attribute_name = jQuery( this ).data( 'attribute_name' ) || jQuery( this ).attr( 'name' );
1028			var value = jQuery( this ).val() || '';
1029
1030			if ( value.length > 0 ) {
1031				chosen ++;
1032			}
1033
1034			count ++;
1035			data[ attribute_name ] = value;
1036		} );
1037
1038		return {
1039			'count': count,
1040			'chosenCount': chosen,
1041			'data': data
1042		};
1043	};
1044
1045	/**
1046	 * Show spinner/loader for ajax.
1047	 */
1048	this.showLoader = function() {
1049		this.$form.block( {
1050			message: null,
1051			overlayCSS: {
1052				background: '#fff',
1053				opacity: 0.6
1054			}
1055		} );
1056	};
1057
1058	/**
1059	 * used in conjection to showLoader() to hide the spinner/loader
1060	 */
1061	this.hideLoader = function() {
1062		this.$form.unblock();
1063	};
1064
1065};

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.