PageSourceSearch

https://www.21bits.ai/wp-content/themes/aihub/liquid/vendors/woocommerce/js/liquid-ajax-filter.js

js 21bits.ai collected 2026-10-05 13:25:26 UTC 9,420 bytes, 318 lines download raw bytes

1; ( function ( $ ) {
2
3	let options = wcLiquid.options || {},
4		currentPage = wcLiquid.paged || 1,
5		loaderHtml = '<span class="row-bg-loader"></span>',
6		ajaxFilter = options.wcAjaxFilter || 'off',
7		ajaxPagination = options.wcAjaxPagination || 'off',
8		paginationType = options.wcAjaxPaginationType || 'classic',
9		paginationButtonText = options.wcAjaxPaginationButtonText || 'Load more products',
10		whatClicked = 'filter', //filter or pagination
11		scrollTracking = true;
12
13	$( document ).ready( ready );
14
15	function ready() {
16
17		let priceFilterWidget = $( '.widget_price_filter' ),
18			productCategoriesWidget = $( '.widget_product_categories, .wc-block-product-categories' ),
19			layeredNavWidget = $( '.widget_layered_nav' ).not( '[class*=yith-woo-ajax-]' ),
20			wcNoticesWrapper = $( '.woocommerce-notices-wrapper' ),
21			ldShopTopbar = $( '.ld-shop-topbar' ),
22			ulProducts = $( 'ul.products' ),
23			wcPagination = $( '.woocommerce-pagination' ),
24			$wcAjaxBtn = null;
25
26		$( 'span.count' ).each( function () {
27			$( this ).text( $( this ).text().replace( /[()]/g, '' ) );
28		} );
29
30		//Enable AJAX pagination
31		if ( isOn( ajaxPagination ) && ulProducts.length && wcPagination.length ) {
32			ajaxPaginationInit();
33		}
34
35		//Enable AJAX filter
36		if ( isOn( ajaxFilter ) && ulProducts.length ) {
37			ajaxFilterInit();
38		}
39
40		let urlParams = new URLSearchParams( window.location.search );
41
42		if ( urlParams.get( 'min_price' ) || urlParams.get( 'max_price' ) || ~window.location.search.indexOf( 'filter_' ) ) {
43			updateProducts();
44		}
45
46		//Update all products by filters
47		function updateProducts() {
48
49			let filters = {},
50				url = new URL( location.href ),
51				selectOrderBy = $( 'select.orderby' ),
52				orderBy = selectOrderBy.val() || 'menu_order',
53				s = urlParams.get( 's' ) || '',
54				chosenFilters = [];
55
56			//if price filter enabled, add price to filter
57			if ( priceFilterWidget.length ) {
58
59				let minPrice = priceFilterWidget.find( '#min_price' ),
60					maxPrice = priceFilterWidget.find( '#max_price' );
61
62				if ( parseInt( minPrice.val() ) !== parseInt( minPrice.data( 'min' ) ) ||
63					parseInt( maxPrice.val() ) !== parseInt( maxPrice.data( 'max' ) ) ) {
64					filters[ 'min_price' ] = parseInt( minPrice.val() );
65					filters[ 'max_price' ] = parseInt( maxPrice.val() );
66				}
67
68			}
69
70			//Add some attributes to filter
71			if ( layeredNavWidget.length ) {
72				$.each( layeredNavWidget.find( '.chosen .count' ), function ( key, chosen ) {
73					let value = filters[ $( chosen ).data( 'filter' ) ] ? filters[ $( chosen ).data( 'filter' ) ] + ',' : '';
74					filters[ $( chosen ).data( 'filter' ) ] = value + $( chosen ).data( 'slug' );
75				} );
76			}
77
78			//Add GET variable to Href
79			$.each( filters, function ( filterKey, filterValue ) {
80				url.searchParams.set( filterKey, filterValue );
81			} );
82
83			url.searchParams.set( 'orderby', orderBy );
84
85			if ( whatClicked === 'filter' ) {
86				url.pathname = url.pathname.replace( 'page/' + currentPage, '' );
87				currentPage = 1;
88			}
89
90			if ( whatClicked === 'pagination' ) {
91				let currentPagination = $( 'span.page-numbers.current' ),
92					oldPage = currentPagination.length ? parseInt( currentPagination.text() ) : 1;
93
94				url.pathname = url.pathname.replace( 'page/' + oldPage, '' ) + 'page/' + currentPage;
95			}
96
97
98			//Add some categiry to filter
99			if ( productCategoriesWidget.length && $( '.woocommerce .widget_product_categories li.chosen a input' ).length ) {
100				const chosenCats = $( '.woocommerce .widget_product_categories li.chosen' ).get();
101				const catsIds = chosenCats.map( cat => cat.querySelector( 'input' ).getAttribute( 'data-term-id' ) );
102				filters[ 'term_id' ] = catsIds;
103			} else if ( wcLiquid.termId ) {
104				filters[ 'term_id' ] = wcLiquid.termId;
105			}
106
107			//Ajax request
108			$.ajax( {
109				type: "post",
110				url: wcLiquid.ajaxUrl,
111				data: {
112					action: "liquid_wc_filter_ajax",
113					filters: filters,
114					page: currentPage,
115					orderby: orderBy,
116					s: s,
117				},
118				beforeSend: function () {
119					if ( 'classic' === paginationType || whatClicked === 'filter' ) {
120						ulProducts.addClass( 'items-loading' ).append( loaderHtml );
121					}
122
123					if ( whatClicked === 'pagination' && 'scroll' === paginationType ) {
124						$wcAjaxBtn.addClass( 'lqd-ajax-btn-loading' );
125					}
126
127					if ( whatClicked === 'pagination' && 'button' === paginationType ) {
128						$wcAjaxBtn.addClass( 'lqd-ajax-btn-loading' );
129					}
130				},
131				success: function ( response ) {
132
133					if ( response.success === true ) {
134
135						let wcNoticesWrapperHtml = $( response.data.html ).find( '.woocommerce-notices-wrapper' ).html() || '',
136							ldShopTopbarHtml = $( response.data.html ).find( '.ld-shop-topbar' ).html() || '',
137							ulProductsHtml = $( response.data.html ).find( 'ul.products' ).html() || '',
138							wcPaginationHtml = $( response.data.html ).find( '.woocommerce-pagination' ).html() || '';
139
140						//Update HTML
141						if ( 'classic' === paginationType || 'filter' === whatClicked ) {
142
143							wcNoticesWrapper.html( wcNoticesWrapperHtml );
144							// ldShopTopbar.html(ldShopTopbarHtml);
145
146							ulProducts.removeClass( 'items-loading' ).html( ulProductsHtml );
147							wcPagination.html( wcPaginationHtml );
148
149							//Init for woocommerce ordering select
150							$( '.woocommerce-ordering' ).on( 'change', 'select.orderby', function () {
151								$( this ).closest( 'form' ).submit();
152							} );
153
154							$( 'form' ).liquidFormInputs();
155
156							$( 'html, body' ).animate( {
157								scrollTop: ulProducts.offset().top - $( '.main-header[data-sticky-header]' ).outerHeight() - 130
158							} )
159
160						}
161
162						if ( 'pagination' === whatClicked && ( 'button' === paginationType || 'scroll' === paginationType ) ) {
163							ulProducts.removeClass( 'items-loading' ).html( ulProducts.html() + ulProductsHtml );
164							wcPagination.removeClass( 'lqd-ajax-btn-loading' );
165							wcPagination.html( wcPaginationHtml );
166						}
167
168						//change URL
169						if ( history.pushState ) {
170							history.pushState( { path: url.href }, '', decodeURIComponent( url.href ) );
171						}
172
173						updatePaginationLinks();
174
175						if ( 'button' === paginationType ) {
176							changeClassicPaginationToButton();
177						}
178
179						if ( 'scroll' === paginationType ) {
180							scrollTracking = true;
181							changeClassicPaginationToScroll();
182						}
183
184						//Remove loader
185						$( '.row-bg-loader' ).remove();
186
187					}
188
189				}
190
191			} );
192
193		}
194
195		function updatePaginationLinks() {
196			$( 'a.page-numbers' ).each( function () {
197				let pathName = location.pathname.replace( '/page/' + currentPage, '' ) + $( this ).attr( 'href' );
198				$( this ).attr( 'href', location.origin + pathName + location.search );
199			} );
200		}
201
202		function changeClassicPaginationToButton() {
203
204			$( '.next.page-numbers', wcPagination )
205				.html( `<span>${ paginationButtonText }</span>` )
206				.parent().addClass( 'wc-pagination-button' );
207
208			$wcAjaxBtn = $( '.wc-pagination-button a', wcPagination );
209
210			wcPagination
211				.addClass( 'wc-pagination-type-button' )
212				.find( 'li:not(.wc-pagination-button)' ).hide();
213		}
214
215		function changeClassicPaginationToScroll() {
216
217			wcPagination
218				.addClass( 'wc-pagination-type-scroll' )
219				.find( 'li' ).hide();
220		}
221
222		function ajaxPaginationInit() {
223
224			if ( 'scroll' === paginationType ) {
225
226				$( window ).on( 'scroll', function () {
227					let scrollHeight = $( this ).scrollTop() + window.innerHeight,
228						ulProductsBottom = ulProducts.offset().top + ulProducts.height();
229
230					if ( scrollTracking && scrollHeight >= ulProductsBottom ) {
231						scrollTracking = false;
232						$( '.next.page-numbers' ).trigger( 'click' );
233					}
234				} );
235
236				changeClassicPaginationToScroll();
237			}
238
239			if ( 'button' === paginationType ) {
240				changeClassicPaginationToButton();
241			}
242
243			$( document ).on( 'click', 'a.page-numbers', function ( e ) {
244				e.preventDefault();
245
246				let currentPagination = $( 'span.page-numbers.current' );
247
248				currentPage = currentPagination.length ? parseInt( currentPagination.text() ) : 1
249
250				if ( $( this ).hasClass( 'next' ) ) {
251					currentPage++;
252				}
253
254				if ( $( this ).hasClass( 'prev' ) ) {
255					currentPage--;
256				}
257
258				if ( $.isNumeric( $( this ).text() ) ) {
259					currentPage = parseInt( $( this ).text() );
260				}
261
262				whatClicked = 'pagination';
263
264				updateProducts();
265			} );
266		}
267
268		function ajaxFilterInit() {
269			//Price filter submit
270			if ( priceFilterWidget.length ) {
271
272				priceFilterWidget.find( 'form' ).on( 'submit', function ( e ) {
273					e.preventDefault();
274					whatClicked = 'filter';
275					updateProducts();
276				} );
277
278			}
279
280			//Change orderby select
281			$( document ).on( 'submit', 'form.woocommerce-ordering', function ( e ) {
282				e.preventDefault();
283				whatClicked = 'filter';
284				updateProducts();
285			} );
286
287			//Categories click
288			if ( productCategoriesWidget.length ) {
289
290				productCategoriesWidget.find( 'a' ).on( 'click', function ( e ) {
291					e.preventDefault();
292					$( this ).parent().toggleClass( 'chosen' );
293					whatClicked = 'filter';
294					updateProducts();
295				} );
296
297			}
298
299			//Attributes filter click
300			if ( layeredNavWidget.length ) {
301
302				layeredNavWidget.find( 'a' ).on( 'click', function ( e ) {
303					e.preventDefault();
304					$( 'a[href="' + $( this ).attr( 'href' ) + '"]' ).parent().toggleClass( 'woocommerce-widget-layered-nav-list__item--chosen chosen' );
305					whatClicked = 'filter';
306					updateProducts();
307				} );
308
309			}
310		}
311
312	}
313
314	function isOn( option ) {
315		return option === 'on';
316	}
317
318} )( 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.