PageSourceSearch

https://gdekomfort.ru/templates/komfort/resource/js/rscomponent/searchline.js

js gdekomfort.ru collected 2026-10-05 02:26:07 UTC 5,324 bytes, 121 lines download raw bytes

1/**
2 * Компонент обеспечивает работу "живого поиска" на странице
3 * Зависит от autoComplete.js
4 */
5new class SearchLine extends RsJsCore.classes.component
6{
7    onDocumentReady()
8    {
9        let searchLine = document.querySelector('.rs-search-line');
10
11        let input = searchLine && searchLine.querySelector('.rs-autocomplete');
12        let resultWrapper = searchLine && searchLine.querySelector('.rs-autocomplete-result');
13        let clearButton = searchLine && searchLine.querySelector('.rs-autocomplete-clear');
14        let cancelController;
15
16        if (input && input.dataset.sourceUrl) {
17            if (clearButton) {
18                input.addEventListener('keyup', (event) => {
19                    clearButton.classList.toggle('d-none', event.target.value === '');
20                });
21
22                clearButton.addEventListener('click', (event) => {
23                    input.value = '';
24                    input.dispatchEvent(new Event('keyup'));
25                    input.dispatchEvent(new Event('keydown'));
26                });
27            }
28
29            let onEnter = (event) => {
30                if (event.key === 'Enter') {
31                    event.target.closest('form').submit();
32                }
33            };
34
35            this.autoComplete = new autoComplete({
36                selector: () => input,
37                searchEngine: () => true,
38                wrapper:false,
39                data: {
40                    src: async () => {
41                        if (cancelController) cancelController.abort();
42                        cancelController = new AbortController();
43                        searchLine.classList.add('in-loading');
44                        let data = await this.utils.fetchJSON(input.dataset.sourceUrl + '&' + new URLSearchParams({
45                            term:this.autoComplete.input.value
46                        }), {
47                            signal: cancelController.signal
48                        });
49                        searchLine.classList.remove('in-loading');
50
51                        return data ? data : [];
52                    },
53                    keys:['value']
54                },
55                resultsList: {
56                    class: '',
57                    maxResults:20,
58                    destination:() => resultWrapper,
59                    position:'beforeend',
60                    noResults: true,
61                    element: (list, data) => {
62                        if (!data.results.length) {
63                            const message = document.createElement("li");
64                            message.setAttribute("class", "no_result");
65                            message.innerHTML = lang.t('Ничего не найдено по вашему запросу');
66                            list.appendChild(message);
67                        }
68                    },
69                },
70                resultItem: {
71                    element: (element, data) => {
72                        let tpl;
73
74                        if (data.value.type === 'product') {
75                            tpl = `<a class="dropdown-item header-search__item" href="${data.value.url}">
76                                        <div class="header-search__item-image">
77                                            <img src="${data.value.image}">
78                                        </div>
79                                        <div class="header-search__item-content">
80                                            <div>${data.value.label}</div>
81                                            <div><strong>${data.value.price}</strong></div>
82                                        </div>
83                                    </a>`;
84                        }
85                        else {
86                            let types = {
87                                'category': lang.t('Категория: '),
88                                'brand': lang.t('Бренд: ')
89                            };
90                            let typeAsString = types[data.value.type] ? types[data.value.type] : '';
91
92                            if (data.value.label == 'Показать все товары') {
93                                tpl = `<a href="{data.value.url}" class="btn">${typeAsString}${data.value.label}</a>`
94                            } else {
95                                tpl = `<a class="dropdown-item" href="${data.value.url}">
96                                            <div class="col">${typeAsString}${data.value.label}</div>
97                                        </a>`;
98                            }
99                        }
100
101                        element.innerHTML = tpl;
102                    },
103                    selected: 'selected'
104                },
105                events: {
106                    input: {
107                        selection: (event) => {
108                            if (event.detail.selection.value) {
109                                input.removeEventListener('keyup', onEnter);
110                                location.href = event.detail.selection.value.url;
111                            }
112                        }
113                    }
114                }
115            });
116
117            input.addEventListener('keyup', onEnter);
118
119        }
120    }
121};

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.