PageSourceSearch

https://onlineborenkopen.nl/wp-content/themes/Impreza/common/js/elements/post-list.js?ver=8.39.2

js onlineborenkopen.nl collected 2026-10-08 07:27:50 UTC 16,284 bytes, 586 lines download raw bytes

1/**
2 * UpSolution Element: Post List
3 */
4;( function( $ ) {
5	"use strict";
6
7	const DELETE_FILTER = null;
8	const PAGINATION_PATTERN = /\/page\/?([0-9]{1,})\/?$/;
9
10	/**
11	 * @type {String} The original URL to return after closing the popup.
12	 */
13	var _originalURL;
14
15	/**
16	 * @param {Node} container.
17	 */
18	function usPostList( container ) {
19		const self = this;
20
21		// Private "variables"
22		self.data = {
23			paged: 1,
24			max_num_pages: 1,
25			pagination: 'none',
26			ajaxUrl: $us.ajaxUrl,
27			ajaxData: {
28				us_ajax_list_pagination: 1,
29			},
30			facetedFilter: {},
31		};
32		self.xhr;
33
34		// Elements
35		self.$container = $( container );
36		self.$list = $( '.w-grid-list', container );
37		self.$loadmore = $( '.g-loadmore', container );
38		self.$pagination = $( 'nav.pagination', container );
39		self.$none = self.$container.next( '.w-grid-none' );
40
41		// Get element settings
42		const $elmSettings = $( '.w-grid-list-json:first', container );
43		if ( $elmSettings.is( '[onclick]' ) ) {
44			$.extend( self.data, $elmSettings[0].onclick() || {} );
45		}
46		$elmSettings.remove();
47
48		self.paginationType = $ush.toString( self.data.pagination );
49		self.hideIsEmpty = self.$container.closest( '.hide_if_inner_list_is_empty' ).length > 0;
50
51		// Bondable events
52		self._events = {
53			addNextPage: self._addNextPage.bind( self ),
54			closePostInPopup: self.closePostInPopup.bind( self ),
55			closePostInPopupByEsc: self.closePostInPopupByEsc.bind( self ),
56			loadPostInPopup: self.loadPostInPopup.bind( self ),
57			navInPopup: self.navInPopup.bind( self ),
58			openPostInPopup: self.openPostInPopup.bind( self ),
59
60			usListOrder: self._usListOrder.bind( self ),
61			usListSearch: self._usListSearch.bind( self ),
62			usListFilter: self._usListFilter.bind( self ),
63
64			usbReloadIsotopeLayout: self.usbReloadIsotopeLayout.bind( self ),
65		};
66
67		// Load posts on button click or page scroll;
68		if ( self.paginationType === 'load_on_btn' ) {
69			self.$loadmore.on( 'mousedown', 'button', self._events.addNextPage );
70
71		} else if ( self.paginationType === 'load_on_scroll' ) {
72			$us.waypoints.add( self.$loadmore, /* offset */'-70%', self._events.addNextPage );
73		}
74
75		// Events
76		self.$container
77			.add( self.$none )
78			.on( 'usListSearch', self._events.usListSearch )
79			.on( 'usListOrder', self._events.usListOrder )
80			.on( 'usListFilter', self._events.usListFilter );
81
82		// Open posts in popup
83		if ( self.$container.hasClass( 'open_items_in_popup' ) ) {
84
85			// Elements
86			self.$popup = $( '.l-popup', container );
87			self.$popupBox = $( '.l-popup-box', self.$popup );
88			self.$popupPreloader = $( '.g-preloader', self.$popup );
89			self.$popupFrame = $( '.l-popup-box-content-frame', self.$popup );
90			self.$popupToPrev = $( '.l-popup-arrow.to_prev', self.$popup );
91			self.$popupToNext = $( '.l-popup-arrow.to_next', self.$popup );
92
93			$us.$body.append( self.$popup );
94
95			// Events
96			self.$list
97				.on( 'click', '.w-grid-item:not(.custom-link) .w-grid-item-anchor', self._events.openPostInPopup );
98			self.$popupFrame
99				.on( 'load', self._events.loadPostInPopup );
100			self.$popup
101				.on( 'click', '.l-popup-arrow', self._events.navInPopup )
102				.on( 'click', '.l-popup-closer, .l-popup-box', self._events.closePostInPopup );
103		}
104
105		// Initialize Masonry.
106		// @see https://isotope.metafizzy.co
107		if ( self.$container.hasClass( 'type_masonry' ) ) {
108			self.$list.imagesLoaded( () => {
109
110				const isotopeOptions = {
111					itemSelector: '.w-grid-item',
112					layoutMode: ( self.$container.hasClass( 'isotope_fit_rows' ) ) ? 'fitRows' : 'masonry',
113					isOriginLeft: ! $( '.l-body' ).hasClass( 'rtl' ),
114					transitionDuration: 0
115				};
116
117				var columnWidth;
118				if ( $( '.size_1x1', self.$list ).length > 0 ) {
119					columnWidth = '.size_1x1';
120				} else if ( $( '.size_1x2', self.$list ).length > 0 ) {
121					columnWidth = '.size_1x2';
122				} else if ( $( '.size_2x1', self.$list ).length >0 ) {
123					columnWidth = '.size_2x1';
124				} else if ( $( '.size_2x2', self.$list ).length > 0 ) {
125					columnWidth = '.size_2x2';
126				}
127				if ( columnWidth ) {
128					columnWidth = columnWidth || '.w-grid-item';
129					isotopeOptions.masonry = { columnWidth: columnWidth };
130				}
131
132				// Run CSS animations locally after rendering elements in Isotope.
133				self.$list.on( 'layoutComplete', () => {
134					if ( _window.USAnimate ) {
135						$( '.w-grid-item.off_autostart', self.$list ).removeClass( 'off_autostart' );
136						new USAnimate( self.$list );
137					}
138					// Trigger scroll event to check positions for `$us.waypoints`.
139					$us.$window.trigger( 'scroll.waypoints' );
140				} );
141
142				self.$list.isotope( isotopeOptions );
143
144				$us.$canvas.on( 'contentChange', () => {
145					self.$list.imagesLoaded( () => {
146						self.$list.isotope( 'layout' );
147					} );
148				} );
149
150			} );
151
152			self.$container.on( 'usbReloadIsotopeLayout', self._events.usbReloadIsotopeLayout );
153		}
154	};
155
156	// Post List API
157	$.extend( usPostList.prototype, {
158
159		/**
160		 * Sets the search string from "List Search".
161		 *
162		 * @event handler
163		 * @param {Event} e The Event interface represents an event which takes place in the DOM.
164		 * @param {String} name
165		 * @param {String} value The search text.
166		 */
167		_usListSearch: function( e, name, value ) {
168			this.applyFilter( name, value );
169		},
170
171		/**
172		 * Sets orderby from "List Order".
173		 *
174		 * @event handler
175		 * @param {Event} e The Event interface represents an event which takes place in the DOM.
176		 * @param {String} name
177		 * @param {String} value The search text.
178		 */
179		_usListOrder: function( e, name, value ) {
180			this.applyFilter( name, value );
181		},
182
183		/**
184		 * Sets values from "List Filter".
185		 *
186		 * @event handler
187		 * @param {Event} e The Event interface represents an event which takes place in the DOM.
188		 * @param {{}} values
189		 */
190		_usListFilter: function( e, values ) {
191			const self = this;
192			$.each( values, self.applyFilter.bind( self ) );
193		},
194
195		/**
196		 * Adds next page.
197		 *
198		 * @event handler
199		 */
200		_addNextPage: function() {
201			const self = this;
202			if ( $ush.isUndefined( self.xhr ) && ! self.$none.is( ':visible' ) ) {
203				self.addItems();
204			}
205		},
206
207		/**
208		 * Apply param to "Post/Product List".
209		 *
210		 * @param {String} name
211		 * @param {String} value
212		 */
213		applyFilter: function( name, value ) {
214			const self = this;
215			if ( $ush.toString( value ) == '{}' ) {
216				value = DELETE_FILTER;
217			}
218
219			// only save
220			if ( name === 'list_filters' ) {
221				self.data.ajaxData[ name ] = value;
222				return;
223			}
224
225			// Reset pagination
226			const pathname = location.pathname;
227			if ( PAGINATION_PATTERN.test( pathname ) ) {
228				history.pushState( {}, '', location.href.replace( pathname, pathname.replace( PAGINATION_PATTERN, '' ) + '/' ) );
229			}
230			self.data.paged = 0;
231
232			if ( self.$container.hasClass( 'for_current_wp_query' ) ) {
233				self.data.ajaxUrl = $ush
234					.urlManager( self.data.ajaxUrl )
235					.set( name, value )
236					.toString();
237
238			} else if ( value === DELETE_FILTER ) {
239				delete self.data.ajaxData[ name ];
240
241			} else {
242				self.data.ajaxData[ name ] = value;
243			}
244
245			if ( ! $ush.isUndefined( self.xhr ) ) {
246				self.xhr.abort();
247			}
248			self.addItems( /* apply filter */true );
249		},
250
251		/**
252		 * Scrolls to the beginning of the list.
253		 */
254		scrollToList: function() {
255			const self = this;
256
257			if ( self.data.paged > 1 ) {
258				return;
259			}
260
261			const offsetTop = $ush.parseInt( self.$container.offset().top );
262			if ( ! offsetTop ) {
263				return;
264			}
265
266			const scrollTop = $us.$window.scrollTop();
267
268			if (
269				! $ush.isNodeInViewport( self.$container[0] )
270				|| offsetTop >= ( scrollTop + window.innerHeight )
271				|| scrollTop >= offsetTop
272			) {
273				$us.$htmlBody
274					.stop( true, false )
275					.animate( { scrollTop: ( offsetTop - $us.header.getInitHeight() ) }, 500 );
276			}
277		},
278
279		/**
280		 * Adds items to element.
281		 *
282		 * @param {Boolean} applyFilter
283		 */
284		addItems: function( applyFilter ) {
285			const self = this;
286
287			self.data.paged += 1;
288			if ( ! applyFilter && self.data.paged > self.data.max_num_pages ) {
289				return;
290			}
291
292			if ( applyFilter ) {
293				self.$container.addClass( 'filtering' );
294
295				// Show spinner for filtering action only if set in options
296				if ( self.$container.hasClass( 'preload_style_spinner' ) ) {
297					self.$loadmore.removeClass( 'hidden' ).addClass( 'loading' );
298				}
299
300				// Always show spinner for pagination action
301			} else {
302				self.$loadmore.removeClass( 'hidden' ).addClass( 'loading' );
303			}
304
305			if ( ! self.hideIsEmpty ) {
306				self.$container.removeClass( 'hidden' );
307			}
308			self.$pagination.addClass( 'hidden' );
309
310			// Get request link and data
311			var ajaxUrl = $ush.toString( self.data.ajaxUrl ),
312				ajaxData = $ush.clone( self.data.ajaxData ),
313				numPage = $ush.rawurlencode( '{num_page}' );
314
315			if ( ajaxUrl.includes( numPage ) ) {
316				ajaxUrl = ajaxUrl.replace( numPage, self.data.paged );
317
318			} else if ( ajaxData.template_vars ) {
319				ajaxData.template_vars = JSON.stringify( ajaxData.template_vars ); // convert for `us_get_HTTP_POST_json()`
320				ajaxData.paged = self.data.paged;
321			}
322
323			self.xhr = $.ajax( {
324				type: 'post',
325				url: ajaxUrl,
326				dataType: 'html',
327				cache: false,
328				data: ajaxData,
329				success: function( html ) {
330
331					// Remove previous items when filtered
332					if ( applyFilter ) {
333						self.$list.html('');
334						self.$none.addClass( 'hidden' );
335					}
336
337					// Reload element settings
338					var $listJson = $( '.w-grid-list-json:first', html );
339					if ( $listJson.is( '[onclick]' ) ) {
340						$.extend( true, self.data, $listJson[0].onclick() || {} );
341					}
342
343					var $items = $( '.w-grid-list:first > *', html );
344
345					// List items loaded
346					$ush.timeout( () => {
347						$us.$document.trigger( 'usPostList.itemsLoaded', [ $items, applyFilter ] );
348					}, 50 );
349
350					if ( self.hideIsEmpty ) {
351						self.$container.toggleClass( 'hidden', $items.length === 0 );
352					}
353
354					// Case when there are no results
355					if ( ! $items.length ) {
356						if ( ! self.$none.length ) {
357							self.$none = $( '.w-grid-none:first', html );
358							if ( ! self.$none.length ) {
359								self.$none = $( html ).filter( '.w-grid-none:first' );
360							}
361							self.$container.after( self.$none );
362						}
363						self.$container.removeClass( 'filtering' );
364						self.$loadmore.addClass( 'hidden' );
365						self.$pagination.addClass( 'hidden' );
366						self.$none.removeClass( 'hidden' );
367						return
368					}
369
370					// Output of results
371					if ( self.$container.hasClass( 'type_masonry' ) ) {
372						self.$list
373							.isotope( 'insert', $items )
374							.isotope( 'reloadItems' );
375					} else {
376						self.$list.append( $items );
377					}
378
379					// Init animation handler for new items
380					if ( window.USAnimate && self.$container.hasClass( 'with_css_animation' ) ) {
381						new USAnimate( self.$list );
382						$us.$window.trigger( 'scroll.waypoints' );
383					}
384
385					// Case with numbered pagination
386					if ( self.paginationType == 'numbered' ) {
387						const $pagination = $( 'nav.pagination', html );
388						if ( $pagination.length && ! self.$pagination.length ) {
389							self.$list.after( $pagination.prop( 'outerHTML' ) );
390							self.$pagination = self.$list.next( 'nav.pagination' );
391						}
392						if ( self.$pagination.length && $pagination.length ) {
393							self.$pagination.html( $pagination.html() ).removeClass( 'hidden' );
394
395						} else {
396							self.$pagination.addClass( 'hidden' );
397						}
398					}
399
400					// Case when the last page is loaded
401					if ( self.data.paged >= self.data.max_num_pages ) {
402						self.$loadmore.addClass( 'hidden' );
403						self.$none.addClass( 'hidden' );
404
405					} else {
406						self.$loadmore.removeClass( 'hidden' );
407					}
408
409					// Adds point to load the next page
410					if ( self.paginationType == 'load_on_scroll' ) {
411						$us.waypoints.add( self.$loadmore, /* offset */'-70%', self._events.addNextPage );
412					}
413
414					$us.$canvas.trigger( 'contentChange' );
415				},
416				complete: function() {
417					self.$container.removeClass( 'filtering' );
418					self.$loadmore.removeClass( 'loading' );
419					if ( self.paginationType == 'load_on_scroll' ) {
420						self.$loadmore.addClass( 'hidden' );
421					}
422					delete self.xhr;
423
424					// Scroll to top of list
425					self.scrollToList();
426				}
427			} );
428		},
429
430		/**
431		 * Reload layout in the Live Builder context.
432		 *
433		 * @event handler
434		 */
435		usbReloadIsotopeLayout: function() {
436			const self = this;
437			if ( self.$container.hasClass( 'with_isotope' ) ) {
438				self.$list.isotope( 'layout' );
439			}
440		},
441	} );
442
443	// Functionality for popup window
444	$.extend( usPostList.prototype, {
445
446		/**
447		 * Open post in popup.
448		 *
449		 * @event handler
450		 * @param {Event} e The Event interface represents an event which takes place in the DOM.
451		 */
452		openPostInPopup: function( e ) {
453			const self = this;
454
455			// If scripts are disabled on a given screen width, then exit
456			if ( $us.$window.width() <= $us.canvasOptions.disableEffectsWidth ) {
457				return;
458			}
459
460			e.stopPropagation();
461			e.preventDefault();
462
463			// Remember original page URL
464			_originalURL = location.href;
465
466			// Set post by index in the list
467			self.setPostInPopup( $( e.target ).closest( '.w-grid-item' ).index() );
468
469			// Show popup
470			self.$popup.addClass( 'active' );
471			$us.$document.trigger( 'usPopupOpened' );
472			$ush.timeout( () => {
473				self.$popupBox.addClass( 'show' );
474			}, 25 );
475		},
476
477		/**
478		 * Load post in popup.
479		 *
480		 * @event handler
481		 */
482		loadPostInPopup: function() {
483			const self = this;
484			self.$container.on( 'keyup', self._events.closePostInPopupByEsc );
485			$( 'body', self.$popupFrame.contents() ).one( 'keyup.usCloseLightbox', self._events.closePostInPopupByEsc );
486		},
487
488		/**
489		 * Navigation in the post popup.
490		 *
491		 * @event handler
492		 * @param {Event} e The Event interface represents an event which takes place in the DOM.
493		 */
494		navInPopup: function( e ) {
495			this.setPostInPopup( $( e.target ).data( 'index' ) );
496		},
497
498		/**
499		 * Sets post by index in the list.
500		 *
501		 * @param {String} url The new value.
502		 */
503		setPostInPopup: function( index ) {
504			const self = this;
505
506			// Get current node and url
507			var $node = $( '> *:eq(' + $ush.parseInt( index ) + ')', self.$list ),
508				url = $ush.toString( $( '[href]:first', $node ).attr( 'href' ) );
509
510			// If there is no href, then exit
511			if ( ! url ) {
512				console.error( 'No url to loaded post' );
513				return;
514			}
515
516			// Gen prev / next node
517			var $prev = $node.prev( ':not(.custom-link)' ),
518				$next = $node.next( ':not(.custom-link)' );
519
520			// Pagination controls switch
521			self.$popupToPrev
522				.data( 'index', $prev.index() )
523				.attr( 'title', $( '.post_title', $prev ).text() )
524				.toggleClass( 'hidden', ! $prev.length );
525			self.$popupToNext
526				.data( 'index', $next.index() )
527				.attr( 'title', $( '.post_title', $next ).text() )
528				.toggleClass( 'hidden', ! $next.length );
529
530			self.$popupPreloader.show();
531			self.$popupBox.off( 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd' );
532			self.$popupFrame.attr( 'src', url + ( url.indexOf( '?' ) > -1 ? '&' : '?' ) + 'us_iframe=1' );
533
534			history.replaceState( null, null, url );
535		},
536
537		/**
538		 * Close post in popup.
539		 *
540		 * @event handler
541		 */
542		closePostInPopup: function() {
543			const self = this;
544
545			self.$popup.addClass( 'closing' );
546			self.$popupFrame.attr( 'src', 'about:blank' );
547			self.$popupBox
548				.removeClass( 'show' )
549				.one( 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', $ush.debounce( () => {
550					self.$popup.removeClass( 'active closing' );
551					self.$popupToPrev.addClass( 'hidden' );
552					self.$popupToNext.addClass( 'hidden' );
553					self.$popupPreloader.show();
554					$us.$document.trigger( 'usPopupClosed' );
555				}, 1 ) );
556
557			// Restore original URL
558			if ( _originalURL ) {
559				history.replaceState( null, null, _originalURL );
560			}
561		},
562
563		/**
564		 * Close post in popup by escape.
565		 *
566		 * @event handler
567		 * @param {Event} e The Event interface represents an event which takes place in the DOM
568		 */
569		closePostInPopupByEsc: function( e ) {
570			const self = this;
571			if ( e.keyCode === $ush.ESC_KEYCODE && self.$popup.hasClass( 'active' ) ) {
572				self.closePostInPopup();
573			}
574		},
575
576	} );
577
578	$.fn.usPostList = function() {
579		return this.each( function() {
580			$( this ).data( 'usPostList', new usPostList( this ) );
581		} );
582	};
583
584	$( () =>
584 $( '.w-grid.us_post_list, .w-grid.us_product_list' ).usPostList() );
585
586} )( 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.