PageSourceSearch

https://almerecity.nl/wp-content/themes/Impreza/common/js/elements/grid.js?ver=8.46.1

js almerecity.nl collected 2026-10-02 11:43:22 UTC 20,482 bytes, 673 lines download raw bytes

1/**
2 * Grid (deprecated)
3 */
4;( function( $, _undefined ) {
5	"use strict";
6
7	const _window = window;
8
9	$us.WGrid = function( container, options ) {
10		const self = this;
11
12		// Elements
13		self.$container = $( container );
14		self.$filters = $( '.g-filters-item', self.$container ); // Built-in filters
15		self.$list = $( '.w-grid-list', self.$container );
16		self.$loadmore = $( '.g-loadmore', self.$container );
17		self.$pagination = $( '> .pagination', self.$container );
18		self.$preloader = $( '.w-grid-preloader', self.$container );
19		self.$style = $( '> style:first', self.$container );
20
21		// Private "Variables"
22		self.loading = false;
23		self.changeUpdateState = false;
24		self.gridFilter = null;
25
26		self.curFilterTaxonomy = '';
27		self.paginationType = self.$pagination.length
28			? 'regular'
29			: ( self.$loadmore.length ? 'ajax' : 'none' );
30		self.filterTaxonomyName = self.$list.data( 'filter_taxonomy_name' )
31			? self.$list.data( 'filter_taxonomy_name' )
32			: 'category';
33
34		// Prevent double init.
35		if ( self.$container.data( 'gridInit' ) == 1 ) {
36			return;
37		}
38		self.$container.data( 'gridInit', 1 );
39
40		// Bindable events
41		self._events = {
42			updateState: self._updateState.bind( self ),
43			updateOrderBy: self._updateOrderBy.bind( self ),
44			initMagnificPopup: self._initMagnificPopup.bind( self ),
45			usbReloadIsotopeLayout: self._usbReloadIsotopeLayout.bind( self ),
46			scrollToGrid: $ush.debounce( self.scrollToGrid.bind( self ), 10 ),
47			addNextPage: self.addNextPage.bind( self ),
48		};
49
50		var $jsonContainer = $( '.w-grid-json', self.$container );
51		if ( $jsonContainer.length && $jsonContainer.is( '[onclick]' ) ) {
52			self.ajaxData = $jsonContainer[0].onclick() || {};
53			if ( ! $us.usbPreview() ) {
54				$jsonContainer.remove();
55			}
56			// In case JSON data container isn't present.
57		} else {
58			self.ajaxData = {};
59			self.ajaxUrl = '';
60		}
61
62		// Open posts in popup
63		if ( self.$container.hasClass( 'open_items_in_popup' ) ) {
64			new $us.usPopup().popupPost( self.$container );
65		}
66
67		if ( self.paginationType != 'none' || self.$filters.length ) {
68			if ( self.ajaxData == _undefined ) {
69				return;
70			}
71
72			self.templateVars = self.ajaxData.template_vars || {};
73			if ( self.filterTaxonomyName ) {
74				self.initialFilterTaxonomy = self.$list.data( 'filter_default_taxonomies' )
75					? self.$list.data( 'filter_default_taxonomies' ).toString().split( ',' )
76					: '';
77				self.curFilterTaxonomy = self.initialFilterTaxonomy;
78			}
79
80			self.curPage = self.ajaxData.current_page || 1;
81			self.infiniteScroll = self.ajaxData.infinite_scroll || 0;
82		}
83
84		if ( self.$container.hasClass( 'with_isotope' ) ) {
85
86			self.$list.imagesLoaded( () => {
87				var smallestItemSelector,
88					isotopeOptions = {
89						itemSelector: '.w-grid-item',
90						layoutMode: ( self.$container.hasClass( 'isotope_fit_rows' ) ) ? 'fitRows' : 'masonry',
91						isOriginLeft: ! $( '.l-body' ).hasClass( 'rtl' ),
92						transitionDuration: 0
93					};
94
95				if ( self.$list.find( '.size_1x1' ).length ) {
96					smallestItemSelector = '.size_1x1';
97				} else if ( self.$list.find( '.size_1x2' ).length ) {
98					smallestItemSelector = '.size_1x2';
99				} else if ( self.$list.find( '.size_2x1' ).length ) {
100					smallestItemSelector = '.size_2x1';
101				} else if ( self.$list.find( '.size_2x2' ).length ) {
102					smallestItemSelector = '.size_2x2';
103				}
104				if ( smallestItemSelector ) {
105					smallestItemSelector = smallestItemSelector || '.w-grid-item';
106					isotopeOptions.masonry = { columnWidth: smallestItemSelector };
107				}
108
109				// Launching CSS animation locally after building elements in isotope.
110				self.$list.on( 'layoutComplete', () => {
111					if ( _window.USAnimate ) {
112						$( '.w-grid-item.off_autostart', self.$list )
113							.removeClass( 'off_autostart' );
114						new USAnimate( self.$list );
115					}
116					// Trigger scroll event to check the positions for $us.waypoints.
117					$us.$window.trigger( 'scroll.waypoints' );
118				} );
119
120				self.$list.isotope( isotopeOptions );
121
122				if ( self.paginationType == 'ajax' ) {
123					self.initAjaxPagination();
124				}
125				$us.$canvas.on( 'contentChange', () => {
126					self.$list.imagesLoaded( () => {
127						self.$list.isotope( 'layout' );
128					} );
129				} );
130
131			} );
132
133			// Events
134			self.$container.on( 'usbReloadIsotopeLayout', self._events.usbReloadIsotopeLayout );
135
136		} else if ( self.paginationType == 'ajax' ) {
137			self.initAjaxPagination();
138		}
139
140		self.$filters.each( ( index, filter ) => {
141			var $filter = $( filter ),
142				taxonomy = $filter.data( 'taxonomy' );
143			$filter.on( 'click', () => {
144				if ( taxonomy != self.curFilterTaxonomy ) {
145					if ( self.loading ) {
146						return;
147					}
148					self.setState( 1, taxonomy );
149					self.$filters.removeClass( 'active' );
150					$filter.addClass( 'active' );
151				}
152			} )
153		} );
154
155		// This is necessary for interaction from the Grid Filter or Grid Order.
156		if ( self.$container.closest( '.l-main' ).length ) {
157			$us.$body
158				.on( 'us_grid.updateState', self._events.updateState )
159				.on( 'us_grid.updateOrderBy', self._events.updateOrderBy );
160		}
161
162		// Events
163		self.$container.on( 'scrollToGrid', self._events.scrollToGrid );
164		self.$list.on( 'click', '[ref=magnificPopup]', self._events.initMagnificPopup );
165
166		// Open Post Image in a Popup
167		if ( $( '[ref=magnificPopupList]:first', self.$list ).length ) {
168			self.initMagnificPopupList();
169		}
170	};
171
172	// Grid API
173	$us.WGrid.prototype = {
174
175		/**
176		 * Update Grid State.
177		 *
178		 * @param {Event} e
179		 * @param {string} queryString Query string containing Grid Filter parameters
180		 * @param {number} page
181		 * @param {object} gridFilter
182		 */
183		_updateState: function( e, queryString, page, gridFilter ) {
184			const self = this;
185			var $container = self.$container;
186			if (
187				! $container.is( '[data-filterable="true"]' )
188				|| ! $container.hasClass( 'used_by_grid_filter' )
189				|| (
190					! $container.is( ':visible' )
191					&& ! $container.hasClass( 'hidden' )
192				)
193			) {
194				return;
195			}
196
197			page = page || 1;
198			self.changeUpdateState = true;
199			self.gridFilter = gridFilter;
200
201			// Is load grid content
202			if ( self.ajaxData === _undefined ) {
203				self.ajaxData = {};
204			}
205
206			if ( ! self.hasOwnProperty( 'templateVars' ) ) {
207				self.templateVars = self.ajaxData.template_vars || {
208					query_args: {}
209				};
210			}
211			self.templateVars.us_grid_filter_query_string = queryString;
212			if ( self.templateVars.query_args !== false ) {
213				self.templateVars.query_args.paged = page;
214			}
215
216			// Related parameters for getting data, number of records for taxonomy, price range for WooCommerce,
217			// etc.
218			self.templateVars.filters_args = gridFilter.filtersArgs || {};
219			self.setState( page );
220
221			// Reset pagination
222			if ( self.paginationType === 'regular' && /page(=|\/)/.test( location.href ) ) {
223				var url = location.href.replace( /(page(=|\/))(\d+)(\/?)/, '$1' + page + '$2' );
224				if ( history.replaceState ) {
225					history.replaceState( document.title, document.title, url );
226				}
227			}
228		},
229
230		/**
231		 * Update Grid orderby.
232		 *
233		 * @param {Event} e
234		 * @param string orderby String for order by params.
235		 * @param {number} page
236		 * @param {object} gridOrder
237		 */
238		_updateOrderBy: function( e, orderby, page, gridOrder ) {
239			const self = this;
240			if (
241				! self.$container.is( '[data-filterable="true"]' )
242				|| ! self.$container.hasClass( 'used_by_grid_order' )
243			) {
244				return;
245			}
246
247			page = page || 1;
248			self.changeUpdateState = true;
249			if ( ! self.hasOwnProperty( 'templateVars' ) ) {
250				self.templateVars = self.ajaxData.template_vars || {
251					query_args: {}
252				};
253			}
254			if ( self.templateVars.query_args !== false ) {
255				self.templateVars.query_args.paged = page;
256			}
257			self.templateVars.grid_orderby = orderby;
258			self.setState( page );
259		},
260
261		/**
262		 * Reload layout in the Live Builder context.
263		 *
264		 * @event handler
265		 */
266		_usbReloadIsotopeLayout: function() {
267			const self = this;
268			if ( self.$container.hasClass( 'with_isotope' ) ) {
269				self.$list.isotope( 'layout' );
270			}
271		},
272
273		// Pagination and Filters functions.
274		initAjaxPagination: function() {
275			const self = this;
276			self.$loadmore.on( 'click', self._events.addNextPage );
277
278			if ( self.infiniteScroll ) {
279				$us.waypoints.add( self.$loadmore, /* offset */'-70%', self._events.addNextPage );
280			}
281		},
282
283		addNextPage: function() {
284			const self = this;
285			if (
286				$ush.isUndefined( self.xhr )
287				&& ! self.loading
288				&& self.curPage < self.ajaxData.max_num_pages
289			) {
290				self.setState( self.curPage + 1 );
291			}
292		},
293
294		setState: function( page, taxonomy ) {
295			const self = this;
296			if ( self.loading && ! self.changeUpdateState ) {
297				return;
298			}
299
300			if (
301				page !== 1
302				&& self.paginationType == 'ajax'
303				&& self.none !== _undefined
304				&& self.none == true
305			) {
306				return;
307			}
308
309			self.none = false;
310			self.loading = true;
311
312			// Hide element by default
313			self.$container
314				.next( '.w-grid-none' )
315				.addClass( 'hidden' );
316
317			// Create params for built-in filter
318			if ( self.$filters.length && ! self.changeUpdateState ) {
319				taxonomy = taxonomy || self.curFilterTaxonomy;
320				if ( taxonomy == '*' ) {
321					taxonomy = self.initialFilterTaxonomy;
322				}
323
324				if ( taxonomy != '' ) {
325					var newTaxArgs = {
326							'taxonomy': self.filterTaxonomyName,
327							'field': 'slug',
328							'terms': taxonomy
329						},
330						taxQueryFound = false;
331					if ( self.templateVars.query_args.tax_query == _undefined ) {
332						self.templateVars.query_args.tax_query = [];
333					} else {
334						$.each( self.templateVars.query_args.tax_query, ( index, taxArgs ) => {
335							if ( taxArgs != null && taxArgs.taxonomy == self.filterTaxonomyName ) {
336								self.templateVars.query_args.tax_query[ index ] = newTaxArgs;
337								taxQueryFound = true;
338								return false;
339							}
340						} );
341					}
342					if ( ! taxQueryFound ) {
343						self.templateVars.query_args.tax_query.push( newTaxArgs );
344					}
345				} else if ( self.templateVars.query_args.tax_query != _undefined ) {
346					$.each( self.templateVars.query_args.tax_query, ( index, taxArgs ) => {
347						if ( taxArgs != null && taxArgs.taxonomy == self.filterTaxonomyName ) {
348							self.templateVars.query_args.tax_query[ index ] = null;
349							return false;
350						}
351					} );
352				}
353			}
354
355			if ( self.templateVars.query_args !== false ) {
356				self.templateVars.query_args.paged = page;
357			}
358
359			if ( self.paginationType == 'ajax' ) {
360				if ( page == 1 ) {
361					self.$loadmore.addClass( 'hidden' );
362				} else {
363					self.$container.addClass( 'loading_items' );
364				}
365				if ( ! self.infiniteScroll ) {
366					self.prevScrollTop = $us.$window.scrollTop();
367				}
368			}
369
370			if ( self.paginationType != 'ajax' || page == 1 ) {
371				self.$preloader.addClass( 'active' );
372				if ( self.$list.data( 'isotope' ) ) {
373					self.$list.isotope( 'remove', self.$container.find( '.w-grid-item' ) );
374					self.$list.isotope( 'layout' );
375				} else {
376					self.$container.find( '.w-grid-item' ).remove();
377				}
378			}
379
380			self.ajaxData.template_vars = JSON.stringify( self.templateVars );
381
382			var isotope = self.$list.data( 'isotope' );
383			// Clear isotope elements on first page load
384			if ( isotope && page == 1 ) {
385				self.$list.html( '' );
386				isotope.remove( isotope.items );
387				isotope.reloadItems();
388			}
389
390			// Abort prev request
391			if ( self.xhr !== _undefined ) {
392				self.xhr.abort();
393			}
394
395			self.xhr = $.ajax( {
396				type: 'post',
397				url: $us.ajaxUrl,
398				data: self.ajaxData,
399				cache: false,
400				beforeSend: function() {
401					// Display the grid before submitting the request
402					self.$container.removeClass( 'hidden' );
403				},
404				success: function( html ) {
405					var $result = $( html ),
406						// Note: Get the `first()` list since there may be several of them due to
407						// the output of grids in `w-grid-none`
408						$container = $( '.w-grid-list', $result ).first(),
409						$pagination = $( '.pagination > *', $result ),
410						$items = $container.children(),
411						smallestItemSelector;
412
413					// Hide the grid if there is no result if action 'Hide this Grid' is enabled
414					self.$container
415						.toggleClass( 'hidden', ! $items.length );
416
417					$container.imagesLoaded( () => {
418						self.beforeAppendItems( $items );
419						//isotope.options.hiddenStyle.transform = '';
420						$items.appendTo( self.$list );
421						$container.html( '' );
422						var $sliders = $items.find( '.w-slider' );
423
424						if ( isotope ) {
425							isotope.insert( $items );
426							isotope.reloadItems();
427						}
428
429						if ( $sliders.length ) {
430							$sliders.each( ( index, slider ) => {
431								$( slider ).usImageSlider().find( '.royalSlider' ).data( 'royalSlider' ).ev.on( 'rsAfterInit', () => {
432									if ( isotope ) {
433										self.$list.isotope( 'layout' );
434									}
435								} );
436							} );
437						}
438
439						if ( isotope ) {
440							if ( self.$list.find( '.size_1x1' ).length ) {
441								smallestItemSelector = '.size_1x1';
442							} else if ( self.$list.find( '.size_1x2' ).length ) {
443								smallestItemSelector = '.size_1x2';
444							} else if ( self.$list.find( '.size_2x1' ).length ) {
445								smallestItemSelector = '.size_2x1';
446							} else if ( self.$list.find( '.size_2x2' ).length ) {
447								smallestItemSelector = '.size_2x2';
448							}
449							if ( isotope.options.masonry ) {
450								isotope.options.masonry.columnWidth = smallestItemSelector || '.w-grid-item';
451							}
452							self.$list.isotope( 'layout' );
453							self.$list.trigger( 'layoutComplete' );
454						}
455
456						if ( self.paginationType == 'ajax' ) {
457
458							if ( page == 1 ) {
459								var $jsonContainer = $result.find( '.w-grid-json' );
460								if ( $jsonContainer.length ) {
461									var ajaxData = $jsonContainer[0].onclick() || {};
462									self.ajaxData.max_num_pages = ajaxData.max_num_pages || self.ajaxData.max_num_pages;
463								} else {
464									self.ajaxData.max_num_pages = 1;
465								}
466							}
467
468							if ( self.templateVars.query_args.paged >= self.ajaxData.max_num_pages || ! $items.length ) {
469								self.$loadmore.addClass( 'hidden' );
470							} else {
471								self.$loadmore.removeClass( 'hidden' );
472								self.$container.removeClass( 'loading_items' );
473							}
474
475							if ( self.infiniteScroll ) {
476								$us.waypoints.add( self.$loadmore, /* offset */'-70%', self._events.addNextPage );
477
478								// If the scroll value has changed, then scroll to the starting position,
479								// as in some browsers this is not true. After loading the data, the scroll is not
480								// calculated correctly.
481							} else if ( Math.round( self.prevScrollTop ) != Math.round( $us.$window.scrollTop() ) ) {
482								$us.$window.scrollTop( self.prevScrollTop );
483							}
484
485						} else if ( self.paginationType === 'regular' && self.changeUpdateState ) {
486							// Pagination Link Correction
487							$( 'a[href]', $pagination ).each( ( _, item ) => {
488								var $item = $( item ),
489									pathname = location.pathname.replace( /((\/page.*)?)\/$/, '' );
490								$item.attr( 'href', pathname + $item.attr( 'href' ) );
491							} );
492							self.$pagination.html( $pagination );
493						}
494
495						// The display a message in the absence of data.
496						var $result_none = $result.next( '.w-grid-none' );
497						if ( self.changeUpdateState && $result_none.length ) {
498							var $none = self.$container.next( '.w-grid-none' );
499							if ( $none.length ) {
500								$none.removeClass( 'hidden' );
501							} else {
502								self.$container.after( $result_none );
503							}
504							// If the result contains a grid that can be Reusable Block, then we will initialize
505							var $nextGrid = $( '.w-grid:first', self.$container.next( '.w-grid-none' ) );
506							if ( $nextGrid.length ) {
507								$nextGrid.wGrid();
508							}
509							self.none = true;
510						}
511
512						// Send the result to the filter grid.
513						if ( self.changeUpdateState && self.gridFilter ) {
514							var $jsonData = $result.filter( '.w-grid-filter-json-data:first' );
515							if ( $jsonData.length ) {
516								self.gridFilter
517									.trigger( 'us_grid_filter.update-items-amount', $jsonData[ 0 ].onclick() || {} );
518							}
519							$jsonData.remove();
520						}
521
522						// Add custom styles to Grid.
523						var customStyles = $( 'style#grid-post-content-css', $result ).html() || '';
524						if ( customStyles ) {
525							if ( ! self.$style.length ) {
526								self.$style = $( '<style></style>' );
527								self.$container.append( self.$style );
528							}
529							self.$style.text( self.$style.text() + customStyles );
530						}
531
532						// Resize canvas to avoid Parallax calculation issues.
533						$us.$canvas.resize();
534						self.$preloader.removeClass( 'active' );
535
536						// Init load animation
537						if ( _window.USAnimate && self.$container.hasClass( 'with_css_animation' ) ) {
538							new USAnimate( self.$container );
539						}
540
541						// List items loaded
542						$ush.timeout( () => {
543							$us.$document.trigger( 'usGrid.itemsLoaded', [ $items ] );
544						}, 1 );
545
546					} );
547
548					// Scroll to top of grid
549					self.$container.trigger( 'scrollToGrid' );
550
551					self.loading = false;
552
553					// Trigger custom event on success, might be used by 3rd party devs
554					// TODO: Remove the trigger and prompt customers to register at "usGrid.itemsLoaded".
555					self.$container.trigger( 'USGridItemsLoaded' );
556
557				},
558				complete: () => {
559					self.$container.removeClass( 'loading_items' );
560					delete self.xhr;
561				},
562			} );
563
564			self.curPage = page;
565			self.curFilterTaxonomy = taxonomy;
566		},
567
568		/**
569		 * Scroll to top of grid
570		 *
571		 * @event handler
572		 */
573		scrollToGrid: function() {
574			const self = this;
575
576			// Check, if it's not load more and orderby
577			if ( self.curPage !== 1 ) {
578				return;
579			}
580
581			var $container = self.$container;
582			if ( $container.hasClass( 'hidden' ) ) {
583				$container = $container.next();
584			}
585
586			const gridPos = $ush.parseInt( $container.offset().top );
587			if ( ! gridPos ) {
588				return;
589			}
590
591			const scrollTop = $us.$window.scrollTop();
592			if (
593				scrollTop >= gridPos
594				|| gridPos >= ( scrollTop + _window.innerHeight )
595			) {
596				$us.$htmlBody
597					.stop( true, false )
598					.animate( { scrollTop: ( gridPos - $us.header.getCurrentHeight() ) }, 500 );
599			}
600		},
601
602		/**
603		 * Overloadable function for themes.
604		 *
605		 * @param $items
606		 */
607		beforeAppendItems: function( $items ) {
608			// Init `Show More` for grid items loaded by AJAX
609			if ( $( '[data-content-height]', $items ).length ) {
610				var handle = $ush.timeout( () => {
611					$( '[data-content-height]', $items ).usCollapsibleContent();
612					$ush.clearTimeout( handle );
613				}, 1 );
614			}
615		},
616	};
617
618	// Popup window functionality
619	$.extend( $us.WGrid.prototype, {
620		/**
621		 * Initializing MagnificPopup for AJAX loaded items.
622		 *
623		 * @param {Event} e
624		 */
625		_initMagnificPopup: function( e ) {
626			e.stopPropagation();
627			e.preventDefault();
628			var $target = $( e.currentTarget );
629			if ( $target.data( 'magnificPopup' ) === _undefined ) {
630				$target.magnificPopup( {
631					type: 'image',
632					mainClass: 'mfp-fade'
633				} );
634				$target.trigger( 'click' );
635			}
636		},
637
638		/**
639		 * Initializes the magnific popup list.
640		 */
641		initMagnificPopupList: function() {
642			const self = this;
643			const globalOpts = $us.langOptions.magnificPopup;
644			self.$list.magnificPopup( {
645				type: 'image',
646				delegate: 'a[ref=magnificPopupList]:visible',
647				gallery: {
648					enabled: true,
649					navigateByImgClick: true,
650					preload: [0, 1],
651					tPrev: globalOpts.tPrev, // Alt text on left arrow
652					tNext: globalOpts.tNext, // Alt text on right arrow
653					tCounter: globalOpts.tCounter // Markup for "1 of 7" counter
654				},
655				image: {
656					titleSrc: 'aria-label'
657				},
658				removalDelay: 300,
659				mainClass: 'mfp-fade',
660				fixedContentPos: true,
661			} );
662		},
663	} )
664
665	$.fn.wGrid = function( options ) {
666		return this.each( function() {
667			$( this ).data( 'wGrid', new $us.WGrid( this, options ) );
668		} );
669	};
670
671	$( () => $( '.w-grid:not(.us_post_list,.us_product_list,.type_carousel)' ).wGrid() );
672
673} )( 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.