PageSourceSearch

https://www.zionbuffalo.org/wp-content/plugins/jet-woo-builder/assets/js/frontend.js?ver=2.3.2.1

js zionbuffalo.org collected 2026-10-02 19:53:20 UTC 17,448 bytes, 615 lines download raw bytes

1( function( $ ) {
2
3	"use strict";
4
5	let JetWooBuilder = {
6
7		init: function() {
8
9			if ( ! window.elementorFrontend || ! window.elementorFrontend.hooks ) {
10				return;
11			}
12
13			window.elementorFrontend.hooks.addAction(
14				'frontend/element_ready/jet-single-images.default',
15				function( $scope ) {
16					$scope.find( '.jet-single-images__loading' ).remove();
17				}
18			);
19
20			window.elementorFrontend.hooks.addAction(
21				'frontend/element_ready/jet-single-tabs.default',
22				function( $scope ) {
23					$scope.find( '.jet-single-tabs__loading' ).remove();
24				}
25			);
26
27			window.elementorFrontend.hooks.addFilter( 'jet-popup/widget-extensions/popup-data', JetWooBuilder.prepareJetPopup );
28
29			$( window ).on( 'jet-popup/render-content/ajax/success', JetWooBuilder.jetPopupLoaded );
30
31			$( document )
32				.on( 'wc_update_cart added_to_cart', JetWooBuilder.handleJetPopupWithWCEvents )
33				.on( 'jet-filter-content-rendered', function ( _, $scope ) {
34					JetWooBuilder.initFilteredContentWidgets( $scope );
35				} )
36				.on( 'click.JetWooBuilder', '.jet-woo-item-overlay-wrap', JetWooBuilder.handleListingItemClick );
37
38			$( document.body ).on( 'wc_cart_emptied', function () {
39				if ( $( '.jet-woo-builder-woocommerce-empty-cart' ).length ) {
40					JetWooBuilder.elementorFrontendInit( $( '.jet-woo-builder-woocommerce-empty-cart' ) );
41				}
42			} );
43
44			$( document ).on( 'jet-ajax-search/show-results/listing', function() {
45				$( '.jet-woo-builder-archive-add-to-cart .add_to_cart_button.ajax_add_to_cart' ).on( 'click', function( e ) {
46					e.preventDefault();
47
48					let _this = $( this );
49
50					if ( _this.attr( 'data-product_id' ) ) {
51						let addToCartData = {};
52
53						$.each( _this[0].dataset, function( key, value ) {
54							addToCartData[ key ] = value;
55						} );
56
57						_this.prop( 'disabled', true );
58
59						$.ajax( {
60							type: 'POST',
61							url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' ),
62							dataType: 'json',
63							data: addToCartData,
64							success: function( response ) {
65								$( document.body ).trigger( 'wc_fragment_refresh' );
66								$( document.body ).trigger( 'added_to_cart' );
67
68								_this.prop( 'disabled', false );
69							},
70							error: function( xhr, status, error ) {
71								_this.prop( 'disabled', false );
72							}
73						} );
74					}
75				} );
76			} );
77
78		},
79
80		registerWidgetHandler: function( widgetName, callback ) {
81
82			if ( ! window.elementorFrontend || ! window.elementorFrontend.hooks ) {
83				$( window ).on( 'elementor/frontend/init', function() {
84					if ( window.elementorFrontend && window.elementorFrontend.hooks ) {
85						window.elementorFrontend.hooks.addAction(
86							'frontend/element_ready/' + widgetName,
87							callback
88						);
89					}
90				} );
91
92				return;
93			}
94
95			window.elementorFrontend.hooks.addAction(
96				'frontend/element_ready/' + widgetName,
97				callback
98			);
99		},
100
101		commonInit: function () {
102
103			if ( window.jetWooBuilderData && window.jetWooBuilderData.single_ajax_add_to_cart ) {
104				let $product = $( '.woocommerce div.product' );
105
106				if ( ! $product.hasClass( 'product-type-external' ) ) {
107					$( document ).on( 'click.JetWooBuilder', '.single_add_to_cart_button:not(.disabled)', JetWooBuilder.singleProductAjaxAddToCart );
108				}
109			}
110
111			if ( navigator.userAgent.indexOf('Safari') !== -1 && navigator.userAgent.indexOf('Chrome') === -1 ) {
112				document.addEventListener( 'click', function ( event ) {
113
114					if ( event.target.matches( '.add_to_cart_button .button-text' ) ) {
115						event.target.parentNode.focus();
116					}
117
118					if ( event.target.matches( '.add_to_cart_button' ) || event.target.matches( '.single_add_to_cart_button' ) ) {
119						event.target.focus();
120					}
121
122				} );
123			}
124
125			$( document.body ).bind( 'country_to_state_changing', function ( event, country, wrapper ) {
126				setTimeout( function () {
127					JetWooBuilder.setAddressFieldsRequiredValidation( wrapper );
128				}, 500 );
129			} );
130
131		},
132
133		setAddressFieldsRequiredValidation: function ( wrapper ) {
134
135			let $widget = wrapper.closest( '.elementor-element' ),
136				settings = JetWooBuilder.getElementorElementSettings( $widget );
137
138			if ( settings && settings.modify_field ) {
139				let locale_fields = $.parseJSON( wc_address_i18n_params.locale_fields );
140
141				if ( locale_fields ) {
142					$.each( locale_fields, function( key, value ) {
143
144						let fields_ids = value.split( ',' );
145
146						$.each( fields_ids, function ( index, id ) {
147
148							let field = wrapper.find( id.trim() );
149
150							if ( field.length ) {
151								if ( field.hasClass( 'jwb-field-required' ) ) {
152									JetWooBuilder.fieldIsRequired( field, true );
153								} else if ( field.hasClass( 'jwb-field-optional' ) ) {
154									JetWooBuilder.fieldIsRequired( field, false );
155								}
156							}
157
158						} );
159
160					} );
161				}
162
163			}
164
165		},
166
167		fieldIsRequired: function ( field, isRequired ) {
168
169			JetWooBuilder.modifyFieldLabelWhitespace( field );
170
171			if ( isRequired ) {
172				field.find( 'label .optional' ).remove();
173				field.addClass( 'validate-required' );
174
175				if ( 0 === field.find( 'label .required' ).length ) {
176					field.find( 'label' ).append( '&nbsp;<abbr class="required" title="' + wc_address_i18n_params.i18n_required_text + '">*</abbr>' );
177				}
178			} else {
179				field.find( 'label .required' ).remove();
180				field.removeClass( 'validate-required woocommerce-invalid woocommerce-invalid-required-field' );
181
182				if ( 0 === field.find( 'label .optional' ).length ) {
183					field.find( 'label' ).append( '&nbsp;<span class="optional">(' + wc_address_i18n_params.i18n_optional_text + ')</span>' );
184				}
185			}
186
187		},
188
189		modifyFieldLabelWhitespace: function ( field ) {
190
191			let label = field.find( 'label' ).html();
192
193			if ( label ) {
194				field.find( 'label' ).html( label.replace( /&nbsp;/g, '' ).trim() );
195			}
196
197		},
198
199		handleInputQuantityValue: function( $scope ) {
200
201			let $eWidget = $scope.closest( '.elementor-widget' ),
202				settings = JetWooBuilder.getElementorElementSettings( $eWidget );
203
204			if ( settings && 'yes' === settings.show_quantity ) {
205				let $cartForm = $scope.find( 'form.cart' );
206
207				$cartForm.on( 'change', 'input.qty', function() {
208
209					if ( '0' === this.value && ! $( this.form ).hasClass( 'grouped_form' ) ) {
210						this.value = '1';
211					}
212
213					let $button = $( this.form ).find( 'button[data-quantity]' );
214
215					$button.attr( 'data-quantity', this.value );
216
217					if ( this.max ) {
218						if ( +this.value > +this.max ) {
219							$button.removeClass( 'ajax_add_to_cart' );
220						} else if ( ! $button.hasClass( 'ajax_add_to_cart' ) ) {
221							$button.addClass( 'ajax_add_to_cart' );
222						}
223					}
224
225				} );
226			}
227
228		},
229
230		jetPopupLoaded : function( event, popupData){
231
232			if ( ! popupData.data.isJetWooBuilder ) {
233				return;
234			}
235
236			const $jetPopup = $( '#' + popupData.data.popupId );
237
238			$jetPopup.addClass( 'woocommerce product single-product quick-view-product' );
239			$jetPopup.find( '.jet-popup__container-content' ).addClass( 'product' );
240
241			setTimeout( function() {
242				$( window ).trigger( 'resize' );
243
244				$( '.jet-popup .variations_form' ).each( function() {
245					$( this ).wc_variation_form();
246				} );
247
248				$( '.jet-popup .woocommerce-product-gallery.images' ).each( function() {
249					$( this ).wc_product_gallery();
250				} );
251			}, 300 );
252
253		},
254
255		prepareJetPopup: function( popupData, widgetData, $scope, event ) {
256
257			if ( widgetData['is-jet-woo-builder'] ) {
258				let $product;
259
260				popupData['isJetWooBuilder'] = true;
261				popupData['templateId'] = widgetData['jet-woo-builder-qv-template'];
262
263				if ( $scope.hasClass( 'elementor-widget-jet-woo-products' ) || $scope.hasClass( 'elementor-widget-jet-woo-products-list' ) ) {
264					$product = $( event.target ).parents( '.jet-woo-builder-product' );
265				} else {
266					$product = $scope.parents( '.jet-woo-builder-product' );
267				}
268
269				if ( $product.length ) {
270					popupData['productId'] = $product.data( 'product-id' );
271				}
272			}
273
274			return popupData;
275
276		},
277
278		mobileHoverOnTouch: function( $item, thumbnail ) {
279			if ( 'undefined' !== typeof window.ontouchstart ) {
280				$item.each( function() {
281
282					let $this = $( this ),
283						$thumbnailLink = $this.find( thumbnail + ' a' ),
284						$adjacentItems = $this.siblings();
285
286					if ( $this.hasClass( 'jet-woo-products__item' ) ) {
287						let $itemContent = $this.not( thumbnail );
288
289						$itemContent.each( function() {
290							let $currentItem = $( this );
291
292							JetWooBuilder.mobileTouchEvent( $this, $currentItem, $adjacentItems );
293						} );
294					}
295
296					JetWooBuilder.mobileTouchEvent( $this, $thumbnailLink, $adjacentItems );
297
298				} );
299			}
300		},
301
302		mobileTouchEvent: function( $target, $item, $adjacentItems ) {
303			$item.on( 'click', function( event ) {
304				if ( ! $target.hasClass( 'mobile-hover' ) ) {
305					event.preventDefault();
306
307					$adjacentItems.each( function() {
308						if ( $( this ).hasClass( 'mobile-hover' ) ) {
309							$( this ).removeClass( 'mobile-hover' );
310						}
311					} );
312
313					$target.addClass( 'mobile-hover' );
314				}
315			} );
316		},
317
318		initCarousel: function( $target, options ) {
319
320			let $eWidget = $target.closest( '.elementor-widget' ),
321				slidesCount = $target.find( '.swiper-slide' ).length,
322				settings = JetWooBuilder.getElementorElementSettings( $eWidget ),
323				eBreakpoints = window.elementorFrontend.config.responsive.activeBreakpoints,
324				defaultOptions = {},
325				slidesToShow = +settings.columns || 4,
326				slideOverflow = settings.slides_overflow_enabled && settings.slides_overflow ? +settings.slides_overflow : 0,
327				spaceBetween = undefined !== settings.space_between_slides ? +settings.space_between_slides : 10,
328				defaultSlidesToShowMap = {
329					mobile: 1,
330					tablet: 2
331				};
332
333			defaultOptions = {
334				slidesPerView: slidesToShow + slideOverflow,
335				spaceBetween: spaceBetween,
336				crossFade: 'fade' === options.effect,
337				handleElementorBreakpoints: true
338			}
339
340			defaultOptions.breakpoints = {};
341
342			let lastBreakpointSlidesToShowValue = slidesToShow;
343
344			Object.keys( eBreakpoints ).reverse().forEach( breakpointName => {
345
346				const defaultSlidesToShow = defaultSlidesToShowMap[ breakpointName ] ? defaultSlidesToShowMap[ breakpointName ] : lastBreakpointSlidesToShowValue;
347				const bpSlidesToShow = +settings[ 'columns_' + breakpointName ] || defaultSlidesToShow;
348				const bpSlideOverflow = settings.slides_overflow_enabled && settings[ 'slides_overflow_' + breakpointName ] ? +settings[ 'slides_overflow_' + breakpointName ] : slideOverflow;
349
350				defaultOptions.breakpoints[ eBreakpoints[ breakpointName ].value ] = {
351					slidesPerView: bpSlidesToShow + bpSlideOverflow,
352					slidesPerGroup: +settings[ 'slides_to_scroll_' + breakpointName ] || options.slidesPerGroup,
353					spaceBetween: undefined !== settings['space_between_slides_' + breakpointName] ? +settings['space_between_slides_' + breakpointName] : spaceBetween
354				};
355
356				lastBreakpointSlidesToShowValue = +settings[ 'columns_' + breakpointName ] || defaultSlidesToShow;
357
358			} );
359
360			if ( options.paginationEnable ) {
361				defaultOptions.pagination = {
362					el: '.swiper-pagination',
363					clickable: true,
364					dynamicBullets: options.dynamicBullets
365				}
366			}
367
368			if ( options.navigationEnable ) {
369				defaultOptions.navigation = {
370					nextEl: '.jet-swiper-button-next',
371					prevEl: '.jet-swiper-button-prev',
372				}
373			}
374
375			let currentDeviceSlidePerView = +settings[ 'columns_' + elementorFrontend.getCurrentDeviceMode() ] || +settings['columns'];
376
377			if ( slidesCount > currentDeviceSlidePerView ) {
378				const Swiper = elementorFrontend.utils.swiper;
379
380				new Swiper( $target, $.extend( {}, defaultOptions, options ) ).then( swiper => {
381					$( document ).trigger( 'jet-woo-builder-swiper-initialized', swiper );
382
383					if ( 'vertical' === options.direction && options.paginationEnable && options.dynamicBullets ) {
384						$target.find( '.swiper-pagination' ).css( 'width', $target.find( '.swiper-pagination-bullet-active' ).width() );
385					}
386				} );
387
388				$target.find( '.jet-arrow' ).show();
389			} else if ( options.direction === 'vertical' ) {
390				$target.addClass( 'swiper-container-vertical' );
391				$target.find( '.jet-arrow' ).hide();
392			} else {
393				$target.find( '.jet-arrow' ).hide();
394			}
395
396		},
397
398		handleJetPopupWithWCEvents: function ( event, fragments, hash, button ) {
399
400			let popupWrapper = $( button ).closest( '.jet-popup' );
401
402			if ( popupWrapper.length && popupWrapper.hasClass( 'quick-view-product' ) ) {
403				$( window ).trigger( {
404					type: 'jet-popup-close-trigger',
405					popupData: {
406						popupId: popupWrapper.attr( 'id' ),
407						constantly: false
408					}
409				} );
410			}
411
412			let purchasePopupData = $( button ).closest( '[data-purchase-popup-id]' );
413
414			if ( purchasePopupData.length ) {
415				let popupId = purchasePopupData.data( 'purchase-popup-id' );
416
417				if ( popupId ) {
418					$( window ).trigger( {
419						type: 'jet-popup-open-trigger',
420						popupData: window.JetPlugins.hooks.applyFilters( 'jet-woo-builder.purchase-popup.data', {
421							popupId: 'jet-popup-' + popupId
422						}, event, fragments, hash, button )
423					} );
424				}
425			}
426
427		},
428
429		singleProductAjaxAddToCart: function( event ) {
430
431			if ( event ) {
432				event.preventDefault();
433			}
434
435			let $form = $( this ).closest('form');
436
437			if( ! $form[0].checkValidity() ) {
438				$form[0].reportValidity();
439
440				return false;
441			}
442
443			let $thisBtn = $( this ),
444				product_id = $thisBtn.val() || '',
445				cartFormData = $form.serialize();
446
447			$.ajax( {
448				type: 'POST',
449				url: window.jetWooBuilderData.ajax_url,
450				data: 'action=jet_woo_builder_add_cart_single_product&add-to-cart=' + product_id + '&' + cartFormData,
451				beforeSend: function () {
452					$thisBtn.removeClass( 'added' ).addClass( 'loading' );
453				},
454				complete: function () {
455					$thisBtn.addClass( 'added' ).removeClass( 'loading' );
456				},
457				success: function ( response ) {
458
459					if ( ! response ) {
460						return;
461					}
462
463					if ( response.error && response.product_url ) {
464						window.location = response.product_url;
465
466						return;
467					}
468
469					if ( 'undefined' === typeof wc_add_to_cart_params ) {
470						return;
471					}
472
473					$( document.body ).trigger( 'wc_fragment_refresh' );
474					$( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash, $thisBtn ] );
475
476					$( '.woocommerce-notices-wrapper' ).html( response.fragments.notices_html );
477
478				},
479			} );
480
481			return false;
482
483		},
484
485		handleListingItemClick: function ( event ) {
486
487			let url = $( this ).data( 'url' ),
488				target = $( this ).data( 'target' ) || false;
489
490			if ( url ) {
491				event.preventDefault();
492
493				if (
494					(window.elementorFrontend && window.elementorFrontend.isEditMode())
495					|| $( event.target ).parents( '.jet-compare-button__link' ).length
496					|| $( event.target ).parents( '.jet-wishlist-button__link' ).length
497					|| $( event.target ).parents( '.jet-quickview-button__link' ).length
498				) {
499					return;
500				}
501
502				if ( '_blank' === target ) {
503					window.open( url );
504					return;
505				}
506
507				window.location = url;
508			}
509
510		},
511
512		getElementorElementSettings: function( $scope ) {
513
514			if ( window.elementorFrontend && window.elementorFrontend.isEditMode() && $scope.hasClass( 'elementor-element-edit-mode' ) ) {
515				return JetWooBuilder.getEditorElementSettings( $scope );
516			}
517
518			return $scope.data( 'settings' ) || {};
519
520		},
521
522		getEditorElementSettings: function( $scope ) {
523
524			let modelCID = $scope.data( 'model-cid' ),
525				elementData;
526
527			if ( ! modelCID ) {
528				return {};
529			}
530
531			if ( ! window.elementorFrontend.hasOwnProperty( 'config' ) ) {
532				return {};
533			}
534
535			if ( ! window.elementorFrontend.config.hasOwnProperty( 'elements' ) ) {
536				return {};
537			}
538
539			if ( ! window.elementorFrontend.config.elements.hasOwnProperty( 'data' ) ) {
540				return {};
541			}
542
543			elementData = window.elementorFrontend.config.elements.data[ modelCID ];
544
545			if ( ! elementData ) {
546				return {};
547			}
548
549			return elementData.toJSON();
550
551		},
552
553		initFilteredContentWidgets: function( $content ) {
554
555			if ( ! window.elementorFrontend || ! window.elementorFrontend.hooks ) {
556				return;
557			}
558
559			let widgetTypes = [
560				'jet-woo-products.default',
561				'jet-woo-products-list.default',
562				'jet-woo-builder-archive-add-to-cart.default',
563				'jet-woo-categories.default',
564				'jet-cart-table.default',
565				'jet-woo-builder-products-loop.default',
566			];
567
568			widgetTypes.forEach( function( widgetType ) {
569				$content
570					.find( '[data-widget_type="' + widgetType + '"]' )
571					.addBack( '[data-widget_type="' + widgetType + '"]' )
572					.each( function() {
573						window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + widgetType, $( this ), $ );
574					} );
575			} );
576
577		},
578
579		elementorFrontendInit: function( $content ) {
580
581			if ( ! window.elementorFrontend || ! window.elementorFrontend.hooks ) {
582				return;
583			}
584
585			$content.find( '[data-element_type]' ).each( function() {
586
587				let $this       = $( this ),
588					elementType = $this.data( 'element_type' );
589
590				if ( ! elementType ) {
591					return;
592				}
593
594				if ( 'widget' === elementType ) {
595					elementType = $this.data( 'widget_type' );
596
597					window.elementorFrontend.hooks.doAction( 'frontend/element_ready/widget', $this, $ );
598				}
599
600				window.elementorFrontend.hooks.doAction( 'frontend/element_ready/global', $this, $ );
601				window.elementorFrontend.hooks.doAction( 'frontend/element_ready/' + elementType, $this, $ );
602
603			} );
604
605		}
606
607	};
608
609	$( window ).on( 'elementor/frontend/init', JetWooBuilder.init );
610
611	JetWooBuilder.commonInit();
612
613	window.JetWooBuilder = JetWooBuilder;
614
615} ( 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.