PageSourceSearch

https://tiogatours.nl/static/TiogaTours/js/scripts-v2.vh36f1a59490.js

js tiogatours.nl collected 2026-10-02 21:24:27 UTC 13,796 bytes, 362 lines download raw bytes

1let dpDialog, dpFilters;
2let regionSearchInitialized = false;
3
4document.addEventListener('DOMContentLoaded', () => {
5    console.log('TiogaTours v2');
6    dpDialog = document.querySelector('#dp-selection');
7    dpFilters = document.querySelectorAll('#dp-filter > input')
8
9    initRouteSearch();
10    initPromoNotification();
11    updateConsentStatus();
12
13    if ((localStorage.getItem('showConsentBar') ?? 'true') === 'true') {
14        let cookieMsgContainer = document.createElement('div');
15
16        document.body.append(cookieMsgContainer);
17        cookieMsgContainer.outerHTML = '<div class="hidden-print" id="consentBar" style="padding:10px 0 30px 0; text-align:center; background-color:rgba(250,250,250,0.97); color: black; position: sticky; bottom:0; font-size:130%; z-index:99999; box-shadow: 0 0 7px black; ">' +
18            '<h2>Cookie-voorkeuren</h2>' +
19            '<p style="font-size:80%;"><a href="/cookies/">Lees meer over onze cookies</a></p>' +
20            '<button style="color:#1a4466; padding:8px 14px; border:2px solid #1a4466; background-color:transparent;" onclick="updateConsentStatus(false, false, false, false); hideConsentBar();">Alles weigeren</button>' +
21            '<button style="color:white; padding:8px 14px; border:2px solid #1a4466; margin-left:30px; background-color:#1a4466;" onclick="updateConsentStatus(true, true, true, true); hideConsentBar();">Alles toestaan</button> ' +
22            '<button style="color:#1a4466; padding:8px 14px; border:2px solid #1a4466; margin-left:30px; background-color:transparent;" onclick="updateConsentStatus(false, false, false, true); hideConsentBar();">Analytisch toestaan</button> ' +
23            '</div>';
24    }
25});
26
27const normalizeString = (string) => {
28    if (string === '' || typeof string !== 'string') return '';
29    return string.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '');
30}
31
32const initRouteSearch = () => {
33    const routeSelector = document.getElementById('route-selector');
34    if (!routeSelector) {
35        return;
36    }
37
38    const input = document.getElementById('route-selector-check');
39    const destinations = routeSelector.querySelectorAll('.rs-route-destinations > input.hidden');
40    destinations.forEach(destination => {
41        destination.addEventListener('change', e => {
42            input.checked = false;
43        });
44    });
45
46    const labels = routeSelector.querySelectorAll('.btn-switch > label');
47    labels.forEach(label => {
48        label.addEventListener('click', e => {
49            e.preventDefault();
50            let switcher = document.getElementById(label.htmlFor);
51            switcher.checked = !switcher.checked;
52        });
53    });
54}
55
56const initDestinationPicker = () => {
57    let dp = document.querySelector('#dp-container');
58    if (!dp) {
59        return;
60    }
61
62    dp.querySelector('#dp-list')
63        .insertAdjacentHTML('beforebegin', '<div class="count"></div>')
64
65    let dpButton = dp.querySelector('.dp-button');
66    let dpQuery = dp.querySelector('.dp-query');
67    let dpDialog = document.querySelector('#dp-selection');
68
69    dpButton.addEventListener('click', () => {
70        toggleDestinationPicker(dp);
71    });
72
73    dpQuery.addEventListener('click', () => {
74        toggleDestinationPicker(dp, true);
75    }, true);
76
77    dpQuery.addEventListener('input', () => {
78        destinationFilter();
79    }, true);
80
81    dpFilters.forEach(
82        filter => filter.addEventListener('change', () => destinationFilter())
83    );
84
85    dpDialog.addEventListener('close', () => {
86        document.querySelector('#dp-container').prepend(document.querySelector('.dp-form'));
87    });
88}
89
90const toggleDestinationPicker = (container, query) => {
91    if (!isTouch) dpDialog.style.top = (container.querySelector('.dp-button').getBoundingClientRect().top + window.scrollY - 20) + 'px';
92
93    if (regions && !regionSearchInitialized) {
94        let destinations = dpDialog.querySelectorAll('li');
95        destinations.forEach(destination => {
96            let idDestination = parseInt(destination.dataset.idDestination);
97            regions.forEach(region => {
98                if (region.id_destination_area === idDestination) {
99                    ;
100                    destination.dataset.search = region.search;
101                    destination.dataset.destination = region.destination_search + ' '
102                        + destination.querySelector('h3').innerText;
103                    return;
104                }
105            });
106        });
107        regionSearchInitialized = true;
108    }
109
110    if (!dpDialog.open || query) {
111        dpDialog.showModal();
112        dpDialog.addEventListener('click', (e) => {
113            if (e.target === dpDialog) dpDialog.close()
114        });
115        dpDialog.prepend(document.querySelector('.dp-form'));
116        dpDialog.querySelector('.dp-query').focus();
117        destinationFilter();
118    } else {
119        dpDialog.querySelector('.dp-query').value = '';
120        dpDialog.close();
121    }
122}
123
124
125const destinationFilter = () => {
126    const queryRegex = /\&f\[query\]=[^\&]*/;
127    let nothing = document.querySelector('#dp-selection ul li.nothing')
128    let queryInput = document.querySelector('.dp-query')
129    let countryFilter = document.querySelector('#dp-filter > input:checked');
130    let query = queryInput ? normalizeString(queryInput.value) : '';
131    let countryFilterOption = countryFilter ? countryFilter.value : '';
132    let count = 0;
133    let foundInOtherCountryCount = 0;
134    let matches = [];
135    let inDestinationName = false;
136    let destinations = dpDialog.querySelectorAll('li');
137
138    if (nothing) nothing.remove();
139
140    destinations.forEach(destination => {
141        let matchContainer = destination.querySelector('.matches');
142        if (!matchContainer) {
143            matchContainer = document.createElement('div');
144            matchContainer.classList.add('matches');
145            destination.appendChild(matchContainer);
146        }
147        matchContainer.innerHTML = '';
148        destination.classList.remove('hidden');
149        destination.classList.remove('foundInOtherCountry');
150        destination.classList.remove('foundInFilter');
151
152        let destinationValue = normalizeString(destination.dataset.destination);
153        let inFilter = false;
154
155        if (query.length > 2) {
156            let found = normalizeString(destination.dataset.search).includes(query);
157            let foundInDestinationName = destinationValue.includes(query);
158
159            if ((!found && !foundInDestinationName)) {
160                destination.classList.add('hidden');
161            } else {
162                inFilter = true;
163                destination.classList.add('foundInFilter');
164            }
165
166            if (found) {
167                let searchableText = destination.dataset.search.split(',');
168                let maxMatches = 5;
169                matches = [];
170                searchableText.forEach(searchableString => {
171                    searchableString = searchableString.trim();
172                    if (matches.indexOf(searchableString) === -1 && normalizeString(searchableString).includes(query)) {
173                        matches.push(searchableString);
174                    }
175                });
176                matches.forEach(match => {
177                    if (maxMatches === 0) {
178                        match = 'en meer…';
179                    }
180                    if (maxMatches < 0) {
181                        return;
182                    }
183
184                    let matchValue = document.createElement('span');
185                    matchValue.innerText = match;
186                    matchContainer.appendChild(matchValue);
187                    maxMatches--;
188                });
189                destination.querySelectorAll('.buttons a').forEach(a => {
190                    a.href = a.href.replace(queryRegex, '');
191                    if (matches.length > 0) {
192                        a.href += '&f[query]=' + query;
193                    }
194                });
195            } else if (foundInDestinationName) {
196                inDestinationName = true;
197                destination.querySelectorAll('.buttons a').forEach(a => {
198                    a.href = a.href.replace(queryRegex, '');
199                });
200            }
201        }
202
203        if (countryFilterOption) {
204            let inCountryFilter = countryFilterOption.length ? destinationValue.includes(countryFilterOption) : true;
205
206            if (!inCountryFilter) {
207                destination.classList.add('hidden');
208            }
209            if (inFilter) {
210                foundInOtherCountryCount++;
211                destination.classList.add('foundInOtherCountry');
212            }
213        }
214    });
215
216    count = dpDialog.querySelectorAll('li:not(.hidden)').length;
217    showCount(count);
218
219    console.log( count, foundInOtherCountryCount);
220    if (count === 0 && foundInOtherCountryCount !== 0) {
221        dpDialog.querySelectorAll('.foundInOtherCountry').forEach(destination => {
222            destination.classList.remove('hidden');
223        });
224        nothingFound(query,
225            `Gevonden, alleen valt deze bestemming nèt buiten je filters. 😅 <br />
226            We laten hem je toch even zien:`
227        );
228    }
229
230
231    if (!inDestinationName && query.length > 2 && count === 0 && foundInOtherCountryCount === 0) {
232        nothingFound(query);
233    }
234
235    if (query.length > 2) {
236        showCount(count);
237    }
238}
239
240const showCount = (count) => {
241    let message = '';
242    if (count > 1) {
243        message = count + ' bestemmingen';
244    } else if (count > 0) {
245        message = count + ' bestemming';
246    }
247    document.querySelector('#dp-container .count').innerText = message;
248}
249
250const nothingFound = (query, message) => {
251    let nothing = document.createElement('li');
252    let defaultMessage =
253        `Hmm, daar hebben we geen resultaten voor in onze routes.<br />
254        Je kan hier zoeken op plaatsen en regio's<br />
255        <br />
256        <a href="/zoeken/?q=${query}">Je kan ook op de hele website zoeken naar "${query}".</a>`;
257    message = message ?? defaultMessage;
258
259    nothing.innerHTML = `<p style="grid-column-start: 1; grid-column-end: 3">${message}</p>`;
260    nothing.classList.add('nothing');
261    document.querySelector('#dp-selection ul').prepend(nothing);
262
263}
264
265const initPromoNotification = () => {
266
267    let container = document.getElementById('promo-notifications');
268    let balloons = Array.from(container?.querySelectorAll('.variant') ?? []);
269    let banner = Array.from(document.querySelectorAll('.banner-container') ?? []);
270
271    let variants = [],
272        pickedVariant,
273        closeEl = document.createElement('a'),
274        storage = storageAvailable('localStorage') ? localStorage : null,
275        hiddenBalloons = storage && storage.getItem('promo-notification-hidden') && JSON.parse(storage.getItem('promo-notification-hidden')) || [];
276
277    closeEl.innerHTML = '&times;';
278    closeEl.classList.add('close');
279    closeEl.href = 'javascript: void null';
280
281    if (
282        balloons.length === 0 ||
283        document.getElementById('map') ||
284        (banner.length === 0 && document.location.pathname !== "/")
285    ) {
286        return;
287    }
288
289    balloons.forEach(t => {
290
291        let num = t.getAttribute('data-chance') ? parseInt(t.getAttribute('data-chance')) : 1,
292            now = new Date().getTime(),
293            valid = (
294                t.getAttribute('data-valid-from') ? new Date(t.getAttribute('data-valid-from')).getTime() < now : true
295            ) && (
296                t.getAttribute('data-valid-till') ? new Date(t.getAttribute('data-valid-till')).getTime() > now : true
297            ),
298            i = 0;
299
300        if (hiddenBalloons.indexOf(t.innerText.trim()) !== -1) {
301            return;
302        }
303
304        if (valid === true) {
305            for (i; i < num; i++) {
306                variants.push(t);
307            }
308        }
309    });
310
311    if (variants.length === 0) {
312        return;
313    }
314
315    pickedVariant = variants[Math.floor(Math.random() * variants.length)];
316    pickedVariant.prepend(closeEl);
317
318    closeEl.addEventListener('click', e => {
319        let variant = e.currentTarget.parentElement;
320        variant.classList.remove('active');
321        e.currentTarget.remove();
322        hiddenBalloons.push(pickedVariant.innerText.trim());
323        if (storage) {
324            storage.setItem('promo-notification-hidden', JSON.stringify(hiddenBalloons));
325        }
326    });
327
328    pickedVariant.classList.add('active');
329}
330
331const storageAvailable = (type) => {
332    try {
333        var storage = window[type],
334            x = '__storage_test__';
335        storage.setItem(x, x);
336        storage.removeItem(x);
337        return true;
338    } catch (e) {
339        return false;
340    }
341}
342
343function updateConsentStatus(ad_user_data, ad_personalization, ad_storage, analytics_storage) {
344    const localStatus = JSON.parse(localStorage.getItem('consentStatus') ?? '{}');
345    const consentStatus = {
346        ad_user_data: ad_user_data ?? ((localStatus.ad_user_data ?? 'denied') === 'granted') ? 'granted' : 'denied',
347        ad_personalization: ad_personalization ?? ((localStatus.ad_personalization ?? 'denied') === 'granted') ? 'granted' : 'denied',
348        ad_storage: ad_storage ?? ((localStatus.ad_storage ?? 'denied') === 'granted') ? 'granted' : 'denied',
349        analytics_storage: analytics_storage ?? ((localStatus.analytics_storage ?? 'denied') === 'granted') ? 'granted' : 'denied',
350    };
351
352    localStorage.setItem('consentStatus', JSON.stringify(consentStatus));
353
354    if (window.gtag) gtag('consent', 'update', consentStatus);
355    if (window.fbq) fbq('consent', ad_storage ?? ((localStatus.ad_storage ?? 'denied') === 'granted') ? 'grant' : 'revoke');
356}
357
358function hideConsentBar() {
359    localStorage.setItem('showConsentBar', 'false');
360    const consentBar = document.getElementById('consentBar');
361    consentBar.parentNode.removeChild(consentBar);
362}

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.