PageSourceSearch

https://www.domaliance.fr/wp-content/plugins/reviews/assets/script/reviews.js?ver=2.0

js domaliance.fr collected 2026-10-04 13:24:29 UTC 18,847 bytes, 548 lines download raw bytes

1const ajaxUrl = params.ajaxUrl;
2let tri = 'new';
3let search = '';
4let codePostal = '';
5let page;
6let firstLoad = true; //logique inversée pour éviter les listeners multiples et pour que ça reste clair
7let isRequestInProgress = false;
8let preUrl = '/localdomaliance'
9let path;
10if (window.location.pathname.includes(preUrl)) {
11    path = preUrl + '/temoignages/';
12} else {
13    path = '/temoignages/';
14    preUrl = '';
15}
16
17document.addEventListener('DOMContentLoaded', function () {
18    if (window.location.pathname === path) {
19        paginationOverseer();
20        //throttle(mutationObserver('pagination'), 300);
21        throttle(mutationObserver('label_addressInput'), 300);
22        loaderBehavior();
23        if (firstLoad) {
24            reviewListener();
25            firstLoad = false;
26        }
27    }
28    //url watcher
29    if (window.location.search.includes("ville")) {
30        let codePostal = new URLSearchParams(window.location.search).get('code_postal');
31        filterReviews('', codePostal, 'new');
32    }
33});
34
35// Le toggle "Voir plus/Voir moins" doit fonctionner sur toutes les pages
36// affichant des blocs d'avis (avis_v2-slider), pas uniquement /temoignages/.
37// On attend que le DOM ET le CSS soient entièrement appliqués (load + fonts + layout)
38// plutôt qu'un délai arbitraire, pour que les mesures scrollHeight/clientHeight soient fiables.
39window.addEventListener('load', () => {
40    const runInit = () => {
41        requestAnimationFrame(() => requestAnimationFrame(seeMoreOrLessInit));
42    };
43    if (document.fonts && document.fonts.ready) {
44        document.fonts.ready.then(runInit);
45    } else {
46        runInit();
47    }
48});
49
50function seeMoreOrLessInit(){
51    const buttons = document.querySelectorAll(".toggle-text");
52    buttons.forEach(button => {
53        const targetId = button.getAttribute("data-target");
54        const text = document.getElementById(targetId);
55        text.classList.add("truncate-text");
56        
57        setTimeout(() => {
58            const isTruncated = text.scrollHeight - text.clientHeight;
59            if (isTruncated > 5) {
60                button.classList.remove("hidden");
61            } else {
62                text.classList.remove("truncate-text");
63            }
64        }, 100);
65
66        // On cible `text` (résolu via data-target) et non un sélecteur de classe : c'est le
67        // même élément que celui qui reçoit truncate-text ci-dessus, l'id est unique et le
68        // contrat est déclaré par le bouton. ReviewsCardRenderer rend la classe
69        // `a_avis-content` (préfixée) — un querySelector('.avis-content') ne matche rien.
70        button.addEventListener("click", () => {
71            const isExpanded = text.classList.contains("expanded");
72            if (!isExpanded) {
73                text.style.maxHeight = text.scrollHeight + "px";
74                text.classList.add("expanded");
75            } else {
76                text.style.maxHeight = text.scrollHeight + "px";
77                void text.offsetHeight;
78                text.style.maxHeight = "4.5em";
79                setTimeout(() => {
80                    text.classList.remove("expanded");
81                }, 300);
82            }
83            button.setAttribute("aria-expanded", !isExpanded);
84            button.textContent = !isExpanded ? "Voir moins" : "Voir plus";
85        });
86    });
87}
88
89function seeMoreOrLess2(){
90    const buttons = document.querySelectorAll(".toggle-text");
91    buttons.forEach(button => {
92        const targetId = button.getAttribute("data-target");
93        const text = document.getElementById(targetId);
94        if(text.classList.contains("truncate-text")){
95            return;
96        }
97        text.classList.add("truncate-text");
98        
99        setTimeout(() => {
100            const isTruncated = text.scrollHeight - text.clientHeight;
101            if (isTruncated > 5) {
102                button.classList.remove("hidden");
103            } else {
104                text.classList.remove("truncate-text");
105            }
106        }, 100);
107    });
108}
109
110function loaderBehavior() {
111    //let container = document.querySelector('#data-container');
112    //let pagination = document.querySelector('#pagination');
113    //let loader = document.querySelector('#loader');
114    ////container.classList.toggle('hide');
115    ////pagination.classList.toggle('hide');
116    //loader.classList.add('hide');
117}
118
119function reviewListener() {
120    selectListener('.a_form-select_tri', (value) => {
121        tri = value;
122        useValue(tri);
123    });
124    selectListener('.a_form-select', (value) => {
125        search = value;
126        useValue(search);
127    });
128    communeListener('.commune', (value) => {
129        codePostal = value;
130        useValue(codePostal);
131    });
132    resetListener(() => {
133        filterReviews('', '', '',);
134    });
135
136}
137
138function useValue(value) {
139    filterReviews(search, codePostal, tri);
140}
141
142function communeListener(node, callback) {
143    if (window.location.search.includes("ville")) {
144        return new URLSearchParams(window.location.search).get('code_postal');
145    } else {
146        waitForElem(node).then((e) => {
147            let parent = e.parentElement;
148            let sibling = parent.previousElementSibling;
149            if (sibling.getAttribute('id') === 'addressInput_avis') {
150                e.addEventListener('click', function () {
151                    callback(e.getAttribute('data-code_postal'));
152                });
153            }
154        });
155        document.querySelector('#addressInput_avis').addEventListener('click', function () {
156            callback(this.getAttribute('data-code_postal'));
157        });
158    }
159}
160
161function selectListener(node, callback) {
162    return waitForElem(node).then((e) => {
163        e.addEventListener('change', throttle(function () {
164            callback(e.value);
165        }));
166    });
167}
168
169function resetSlField() {
170    let slField = document.querySelector('#addressInput_avis');
171    slField.value = '';
172    slField.setAttribute('data-code_postal', '');
173    slField.setAttribute('data-code_ville', '');
174}
175
176function resetListener() {
177    let reset = document.querySelector('.btn_ag ');
178    reset.addEventListener('click', function () {
179        filterReviews('', '', 'new').then(r => {
180            resetSlField();
181        });
182    });
183}
184
185/**
186 * Generates a request to the specified URL with the provided type, action, and data.
187 *
188 * @return {Promise} A Promise that resolves with the response text if successful, or rejects with an error message.
189 * @param search
190 * @param codePostal
191 * @param tri
192 */
193function filterReviews(search, codePostal, tri) {
194    codePostal = codePostal ?? '';
195    let data = {
196        search: search,
197        tri: tri,
198        codePostal: codePostal,
199    }
200    let loader = document.querySelector('#loader');
201    let container = document.querySelector('#data-container');
202    let pagination = document.querySelector('#pagination');
203    loaderBehavior();
204    makeRequest(ajaxUrl, 'POST', 'reviewsAjaxHandler', data).then(r => {
205        try {
206            let result = JSON.parse(r);
207            if (result.success && result.data) {
208                result = result.data;
209                let container = document.querySelector('#data-container');
210                let pagination = document.querySelector('#pagination');
211                container.innerHTML = '';
212                pagination.innerHTML = '';
213                loaderBehavior();
214                if (result['renderCards']) {
215                    appendNewCards(result['renderCards'], container);
216                    new StoreLocatorBehavior('#form-field-communeHome', '#submit-button');
217                }
218                if (result['pagination']) {
219                    appendNewPagination(result['pagination'], pagination);
220                    activePageCorrection();
221                    paginationOverseer();
222                }
223
224
225            } else {
226                console.error('Failed to fetch new data:', result.message);
227            }
228        } catch (error) {
229            console.error('Error parsing JSON response:', error);
230        } finally {
231        }
232    })
233        .catch(error => console.error('Error fetching new data:', error));
234}
235
236function activePageCorrection() {
237    let activePage = getActivePage();
238    let pagination = document.querySelector('.paginationjs-pages');
239    let activePagination = pagination.querySelector('.active');
240    activePagination = parseInt(activePagination.getAttribute('data-num'));
241    if (activePage !== activePagination) {
242        activePagination.classList.remove('active');
243        activePagination = pagination.querySelector(`[data-num="${activePage}"]`);
244        activePagination.classList.add('active');
245    }
246}
247
248function appendNewCards(html, container) {
249    return container.innerHTML = html;
250}
251
252function appendNewPagination(pagination, paginationjs) {
253    return paginationjs.innerHTML = pagination;
254}
255
256
257function appendLoader(loader) {
258    let container = document.querySelector('#data-container');
259    container.innerHTML = loader;
260}
261
262
263function hideCards(cards, page) {
264    if (cards.length > 0) {
265        cards.forEach((e) => {
266            if (parseInt(e.getAttribute('page')) !== page) {
267                e.classList.add('hide');
268                window.scrollTo(0, 0);
269            } else {
270                e.classList.remove('hide');
271            }
272        });
273    }
274}
275
276function setCurrentPage(page, pagination) {
277    for (let i = 0; i < pagination.length; i++) {
278        if (parseInt(pagination[i].getAttribute('data-num')) === page) {
279            pagination[i].classList.add('active');
280        } else {
281            pagination[i].classList.remove('active');
282        }
283    }
284}
285
286function paginationLayout(page, next, prev, paginationElements, activePage = 1) {
287    let maxPage = paginationElements[0].getAttribute('maxpage');
288    maxPage = parseInt(maxPage);
289    let excludedLabels = ['', '1', '2', '19', '...', maxPage, activePage]; // 2 et 5 seront transformés en ...
290    //disable previous and next buttons
291    if (activePage === 1) {
292        prev.classList.add('disabled');
293        prev.setAttribute('data-num', activePage);
294    } else {
295        prev.classList.remove('disabled');
296        prev.setAttribute('data-num', activePage - 1);
297    }
298    if (activePage === maxPage) {
299        next.classList.add('disabled');
300        next.setAttribute('data-num', activePage);
301    } else {
302        next.classList.remove('disabled');
303        next.setAttribute('data-num', activePage + 1);
304    }
305    paginationElements.forEach((page) => {
306        let pageNum = page.getAttribute('data-num');
307        if (pageNum === '') return;
308        let pageNumber = parseInt(pageNum);
309        if ((pageNumber < activePage - 3 || pageNumber >
309 activePage + 3) && (pageNumber !== 1 && pageNumber !== 2 && pageNumber !== 19 && pageNumber !== maxPage)) {
310            page.classList.add('hide');
311        } else {
312            page.classList.remove('hide');
313        }
314        if (activePage >= 6) {
315            if (pageNumber === 2) {
316                page.classList.add('paginationjs-ellipsis');
317                page.classList.add('disabled');
318                page.innerHTML = '<a class="disabled">...</a>';
319            }
320        } else {
321            if (pageNumber === 2) {
322                page.classList.remove('paginationjs-ellipsis');
323                page.classList.remove('disabled');
324                page.innerHTML = '<a>2</a>';
325            }
326        }
327
328        if (activePage <= 14) {
329            if (pageNumber === 19) {
330                page.classList.add('paginationjs-ellipsis');
331                page.classList.add('disabled');
332                page.innerHTML = '<a class="disabled">...</a>';
333            }
334        } else {
335            if (pageNumber === 19) {
336                page.classList.remove('paginationjs-ellipsis');
337                page.classList.remove('disabled');
338                page.innerHTML = '<a>19</a>';
339            }
340        }
341    });
342}
343
344function paginationOverseer() {
345    waitForElem('.paginationjs-pages').then((e) => {
346        let pagination = document.querySelector('.paginationjs-pages');
347        let cards = document.querySelectorAll('.a_avis-card');
348        let paginationElements = pagination.querySelectorAll('.J-paginationjs-page');
349        let next = pagination.querySelector('.paginationjs-next');
350        let prev = pagination.querySelector('.paginationjs-prev');
351        paginationLayout(page, next, prev, paginationElements);
352
353        function paginationClickHandler(pagi) {
354            return function () {
355                if (pagi.classList.contains('disabled')) {
356                    return;
357                }
358                let page = parseInt(pagi.getAttribute('data-num'));
359                // paginationLayout(page, next, prev, paginationElements);
360                hideCards(cards, page);
361                setCurrentPage(page, paginationElements);
362                seeMoreOrLess2();
363
364                let activePage = getActivePage();
365                paginationLayout(page, next, prev, paginationElements, activePage);
366            };
367        }
368
369        paginationElements.forEach((pagi) => {
370            pagi.addEventListener('click', paginationClickHandler(pagi));
371        });
372    });
373}
374
375function getActivePage() {
376    let pagination = document.querySelector('.paginationjs-pages');
377    let activePage = pagination.querySelector('.active');
378    activePage = activePage.getAttribute('data-num');
379    activePage = parseInt(activePage);
380    // let next = pagination.querySelector('.paginationjs-next');
381    // let prev = pagination.querySelector('.paginationjs-prev');
382    // let maxPage = pagination.getAttribute('maxPage');
383    // maxPage = parseInt(maxPage);
384    return activePage;
385}
386
387// Fonction plus utilisée
388function storeLocatorRepositionner(page, activePage, maxPage) {
389    let dataContainer = document.querySelector('#data-container');
390    let avis = dataContainer.querySelectorAll('.a_avis-card');
391    let storeLocator = document.querySelector('#store-locator-avis-clone');
392    let url = window.location.href;
393    if (url.includes('localdomaliance') || 'domaliance') {
394        for (let i = 0; i < avis.length; i++) {
395            let newPosition = 0;
396            if (avis.length < 3) {
397                avis[i].insertAdjacentElement('afterend', storeLocator);
398            } else {
399                newPosition = (9 * activePage) - 4;
400                avis[newPosition].insertAdjacentElement('afterend', storeLocator);
401            }
402        }
403    } else {
404        for (let i = 0; i < avis.length; i++) {
405            let newPosition = 0;
406            if (avis.length < 3) {
407                avis[i].insertAdjacentElement('afterend', storeLocator);
408            } else {
409                newPosition = (9 * activePage) - 6;
410                avis[newPosition].insertAdjacentElement('afterend', storeLocator);
411            }
412        }
413    }
414
415    const formFieldCommuneHome = "#form-field-communeHome";
416    const submitButton = "#submit-button";
417    new StoreLocatorBehavior(formFieldCommuneHome, submitButton);
418}
419
420
421//Tools
422function waitForElem(selector, parent = document) {
423    return new Promise((resolve) => {
424        if (parent) {
425            const target = parent.querySelector(selector);
426            if (target) {
427                return resolve(target);
428            }
429            const observer = new MutationObserver((mutations) => {
430                const target = parent.querySelector(selector);
431                if (target) {
432                    resolve(target);
433                    observer.disconnect();
434                }
435            });
436            observer.observe(parent, {
437                childList: true,
438                subtree: true,
439            });
440        }
441    });
442}
443
444function throttle(callback, delay = 50) {
445    let lastCallTime = 0;
446    let timerId;
447    return function () {
448        let currentTime = Date.now();
449        let elapsedTime = currentTime - lastCallTime;
450        if (elapsedTime < delay) {
451            clearTimeout(timerId);
452            timerId = setTimeout(() => {
453                lastCallTime = Date.now();
454                callback.apply(this, arguments);
455            }, delay);
456        } else {
457            lastCallTime = currentTime;
458            callback.apply(this, arguments);
459        }
460    };
461}
462
463
464function makeRequest(url, type, action, data) {
465    return new Promise((resolve, reject) => {
466        if (isRequestInProgress) {
467            reject("Another request is already in progress");
468            return;
469        }
470        isRequestInProgress = true;
471
472        // Show loader
473        const loader = document.querySelector('#loader');
474        if (loader) {
475            loader.classList.remove('hide');
476        }
477
478        let xhr = new XMLHttpRequest();
479
480        if (!xhr) {
481            reject("XMLHttpRequest not supported");
482            return;
483        }
484
485        xhr.open(type, url, true);
486        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
487
488        let queryString = "action=" + action + "&";
489        queryString += Object.keys(data)
490            .map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
491            .join("&");
492
493        xhr.send(queryString);
494
495        xhr.onreadystatechange = function () {
496            try {
497                if (xhr.readyState === XMLHttpRequest.DONE) {
498                    if (xhr.status === 200) {
499                        resolve(xhr.responseText);
500                    } else {
501                        reject("There was a problem with the request. Status: " + xhr.status);
502                    }
503                    isRequestInProgress = false;
504
505                    // Hide loader
506                    if (loader) {
507                        loader.classList.add('hide');
508                    }
509                }
510            } catch (e) {
511                reject("Caught Exception: " + e.description);
512                isRequestInProgress = false;
513
514                // Hide loader in case of error
515                if (loader) {
516                    loader.classList.add('hide');
517                }
518            }
519        };
520    });
521}
522
523
524function mutationObserver(target) {
525    if (!target) return;
526    try {
527        const targetElement = document.getElementById(target);
528
529        if (!targetElement) {
530            throw new Error('Target element not found');
531        }
532        const config = {attributes: true, childList: true, subtree: true};
533
534        const handleMutations = function (mutationsList, observer) {
535            for (const mutation of mutationsList) {
536                if (mutation.type === 'childList') {
537                    reviewListener();
538                } else if (mutation.type === 'attributes') {
539
540                }
541            }
542        };
543        const observer = new MutationObserver(handleMutations);
544        observer.observe(targetElement, config);
545    } catch (error) {
546        console.error('Error setting up mutation observer:', error);
547    }
548}

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.