PageSourceSearch

https://ytf.no/wp-content/plugins/algolia-live-search/public/js/algolia-live-search-public.js?ver=29

js ytf.no collected 2026-10-02 19:52:06 UTC 7,420 bytes, 280 lines download raw bytes

1
2const { autocomplete, getAlgoliaResults } = window['@algolia/autocomplete-js'];
3const searchClient = algoliasearch(algolia_live.application_id, algolia_live.search_api_key);
4
5(function ($) {
6	'use strict';
7
8	/**
9	 * All of the code for your public-facing JavaScript source
10	 * should reside in this file.
11	 *
12	 * Note: It has been assumed you will write jQuery code here, so the
13	 * $ function reference has been prepared for usage within the scope
14	 * of this function.
15	 *
16	 * This enables you to define handlers, for when the DOM is ready:
17	 *
18	 * $(function() {
19	 *
20	 * });
21	 *
22	 * When the window is loaded:
23	 *
24	 * $( window ).load(function() {
25	 *
26	 * });
27	 *
28	 * ...and/or other possibilities.
29	 *
30	 * Ideally, it is not considered best practise to attach more than a
31	 * single DOM-ready or window-load handler for a particular page.
32	 * Although scripts in the WordPress core, Plugins and Themes may be
33	 * practising this, we should strive to set a better example in our own work.
34	 */
35
36})(jQuery);
37
38
39var c = 0;
40var autoStart = 0;
41var queryStart = 0;
42const searchInput = 'input[name=s]';
43const selector = '#algoliaL_autocomplete';
44
45var timer = '';
46
47jQuery(document).ready(function () {
48
49	if (algolia_live.autocomplet_live_enabled) {
50
51		jQuery(searchInput).not(jQuery('#adminbarsearch').find(searchInput)).each(function (index, value) {
52			var selectorIndex = selector + index;
53			var newLine = jQuery('<div id="algoliaL_autocomplete' + index + '" class="algoliaL_autocomplete"></div>');
54			jQuery(this).after(newLine);
55			jQuery(this).hide();
56			autocomplete({
57				container: selectorIndex, //Define where your search box goes in the DOM
58				placeholder: 'Søk her...', //Define placeholder text
59				openOnFocus: true, //If true, dropdown appears as soon as users focuses the input to display trending searches 
60				// debug: true, //If true, keeps the panel open when inspecting elements in your browser DevTools
61				getSources({ query, state }) {
62					return algoliaAutocompleteFunc({ query, state });
63				},
64				detachedMediaQuery: 'none',
65				onStateChange({ state }) {
66					if (state.isOpen == 1) {
67						setTimeout(function () {
68							jQuery('body').addClass('body-freeze');
69							jQuery('body').addClass('search-active');
70							jQuery('.overlay').addClass('active');	
71						},350)
72					}
73					else {
74						setTimeout(function () {
75							jQuery('body').removeClass('body-freeze');
76							jQuery('body').removeClass('search-active');
77							jQuery('.overlay').removeClass('active');
78						},350)
79						
80					}
81				},
82
83				renderNoResults({ render, html, state }, root) {
84
85					if (autoStart && queryStart && state.status == 'idle') {
86						render(
87							html`
88					<div class="aa-PanelLayout aa-Panel--scrollable no-result">
89					  Ingen resultater samsvarte med søket ditt "${state.query}"
90					</div>
91				  `,
92							root
93						)
94
95					}
96					else {
97						render(
98							html``,
99							root
100						)
101					}
102				},
103			});
104
105			if (algolia_live.general_settings.search_field_active_page_load == 1) {
106				jQuery(selectorIndex + ' .aa-Input').focus();
107			}
108
109			jQuery(selectorIndex + ' .aa-Input').keypress(function (e) {
110				var key = e.which;
111				if (key == 13)  // the enter key code
112				{
113					location.href = '/?s=' + jQuery(selectorIndex + ' .aa-Input').val();
114					return false;
115				}
116			});
117		});
118
119		jQuery('html').click(function (e) {
120			if (!jQuery(e.target).hasClass('aa-Input')) {
121				jQuery(".aa-Panel").remove();
122			}
123		});
124
125
126	}
127});
128
129function multiIndexQueries(query) {
130	var queryVal = [];
131	var count = 0;
132	jQuery.each(algolia_live.indices, function (index, value) {
133		if(index==='searchable_posts'){
134		var obj = {
135			sourceId: index,
136			getItems() {
137
138				return getAlgoliaResults({
139					searchClient,
140					queries:
141						[{
142							indexName: value.name,
143							query,
144							params: {
145								hitsPerPage: value.max_suggestions,
146								attributesToSnippet: ['name:10'],
147								snippetEllipsisText: '…',
148							},
149						}],
150					transformResponse({ hits }) {
151						return hits;
152					},
153				});
154			},
155			templates: {
156				header({ state, source, items, html }) {
157					return html`<div class="header-wrapper tax_${value.label}"><div class="header-title">Viser resultater for "${query}"</div></div>`;
158				},
159				item({ item, components, html }) {
160    if (item.post_id) {
161		count++;
162        
163        const excerptText = item.post_excerpt.replace(/<[^>]*>/g, '');
164
165		//taxonomy mapping for different post types
166        const taxonomyKeyMap = {
167			'product': 'product_cat',
168			'post': 'category',
169			'courses': 'course_category',
170			'medlems_fordel': 'fordel_kategori'
171		};
172
173		const key = taxonomyKeyMap[item.post_type]; 
174
175		// Safely get the first item from the array, or empty if it doesn't exist
176		let category = item?.taxonomies[key]?.[0] ?? '';
177
178        const thumbnailUrl = item.images && item.images.thumbnail && item.images.thumbnail.url 
179            ? item.images.thumbnail.url 
180            : algolia_live_path + '/no-img.jpg';
181        
182        return html`<div class="search-result-item type-${item.post_type}">
183		<a href="${item.permalink}">
184            <div class="entry-thumbnail">
185                <img width="50" height="50" src="${thumbnailUrl}" class="attachment-thumbnail size-thumbnail wp-post-image" alt="" decoding="async" loading="lazy" />
186            </div>
187            <div class="entry-text-content">
188                <div class="entry-category">${category}</div>
189                ${item.post_type === 'post' ? html`<div class="entry-date">${item.post_date_formatted}</div>` : ''}
190                ${item.post_type === 'courses' ? html`<div class="meta-data"><div class="entry-from-date">${item.from_date}</div><div class="entry-location">${item.location}</div></div>` : ''}
191                <h2 class="entry-title">${item.post_title}</h2>
192                <div class="entry-summary">${excerptText}</div>
193            </div></a>
194        </div>`;
195    }
196
197
198				},
199				footer({ state, source, item, html }) {
200					
201					footerRendered = true;
202					if (jQuery('.aa-Panel.below_another').length == 0) {
203						jQuery(".aa-Panel").addClass(algolia_live.general_settings.position_result_indices);
204					}
205
206						var show_all_text = 'Se alle søkeresultater';
207						if (algolia_live.general_settings.show_all_text)
208							show_all_text = algolia_live.general_settings.show_all_text;
209						
210						//only add see all if item count is 5 or more
211						if(count>=5){
212						return html`
213					<div>
214						<a class="site-btn w-100" href="/?s=${query}">${show_all_text}</a>
215					</div>
216					`;
217						}
218				},
219			},
220
221
222		};
223
224		queryVal.push(obj);
225		}
226	});
227	queryStart = 1;
228	return queryVal;
229}
230
231async function algoliaAutocompleteFunc({ query, state }) {
232	if (query.length >= algolia_live.general_settings.num_char_to_trigger) {
233		if (algolia_live.general_settings.delay_before_trigger) {
234			const d = new Date();
235			let ms = d.getMilliseconds();
236
237			await delayAlgolia(algolia_live.general_settings.delay_before_trigger);
238
239			const e = new Date();
240			let ems = e.getMilliseconds();
241			autoStart = 1;
242
243		}
244		else {
245			autoStart = 1;
246		}
247
248		if (autoStart) {
249			if (!query) {
250				return [];
251			}
252			return multiIndexQueries(query);
253		}
254	}
255	else {
256		autoStart = 0;
257		return [];
258	}
259}
260
261function delayAlgolia(ms) {
262
263	clearTimeout(timer);
264
265	return new Promise(resolve => {
266		timer = setTimeout(resolve, ms);
267	});
268
269}
270jQuery(document).ready(function () {
271	jQuery('.aa-SourceHeader').remove();
272});
273
274
275
276
277
278
279
280

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.