PageSourceSearch

https://shop.mts.by/local/templates/new-design/components/bitrix/s…/header_search/script.js?17476501047480

js mts.by collected 2026-10-01 10:18:49 UTC 7,480 bytes, 246 lines download raw bytes

1class JSHeaderSearch
2{
3    cache = {};
4    params = {};
5
6    processing = false;
7    pending = false;
8    
9    form = null;
10    dropContainer = null;
11    resultContainer = null;
12    input = null;
13    loader = null;
14    empty = null;
15    reset = null;
16    searchQueryRemoveButtonList = null;
17    debounceTimer = null;
18
19    constructor(arParams) {
20        let self = this;
21
22        self.params = {
23            'AJAX_PAGE': arParams.AJAX_PAGE,
24            'SEARCH_HISTORY_AJAX': arParams.SEARCH_HISTORY_AJAX,
25            'FORM_ID': arParams.FORM_ID,
26            'DROP_CONTAINER_ID': arParams.DROP_CONTAINER_ID,
27            'RESULT_CONTAINER_ID': arParams.RESULT_CONTAINER_ID,
28            'INPUT_ID': arParams.INPUT_ID,
29            'LOADER_ID': arParams.LOADER_ID,
30            'EMPTY_ID': arParams.EMPTY_ID,
31            'RESET_ID': arParams.RESET_ID,
32            'SEARCH_ALL_ID': arParams.SEARCH_ALL_ID,
33            'SEARCH_QUERY_REMOVE_CLASS': arParams.SEARCH_QUERY_REMOVE_CLASS,
34            'MIN_QUERY_LEN': parseInt(arParams.MIN_QUERY_LEN) ?? 3,
35        };
36
37        BX.ready(function() {
38            self.init();
39        });
40    }
41
42    init() {
43        this.form = document.getElementById(this.params.FORM_ID);
44        this.dropContainer = document.getElementById(this.params.DROP_CONTAINER_ID);
45        this.resultContainer = document.getElementById(this.params.RESULT_CONTAINER_ID);
46        this.input = document.getElementById(this.params.INPUT_ID);
47        this.loader = document.getElementById(this.params.LOADER_ID);
48        this.empty = document.getElementById(this.params.EMPTY_ID);
49        this.reset = document.getElementById(this.params.RESET_ID);
50        this.searchQueryRemoveButtonList = document.querySelectorAll('.' + this.params.SEARCH_QUERY_REMOVE_CLASS);
51
52        this.initHandlers();
53    }
54
55    initHandlers() {
56        let self = this;
57        
58        self.form.addEventListener('submit', function(event) {
59            event.preventDefault();
60            self.loaderStart();
61            self.addQueryToSearchHistory();
62        })
63
64        self.input.addEventListener('input', function() {
65            let inputValueLength = self.input.value.length;
66            let minInputValueLength = self.params.MIN_QUERY_LEN;
67
68            if (inputValueLength >= minInputValueLength) {
69                self.onChange();
70            }
71            else if (inputValueLength < minInputValueLength) {
72                self.clearResult();
73            }
74        });
75
76        self.reset.addEventListener('click', function() {
77            self.input.value = '';
78            self.clearResult();
79        });
80
81        self.searchQueryRemoveButtonList.forEach(function(button){
82            button.addEventListener('click', function(event) {
83                let target = event.target;
84
85                let queryBlock = target.closest('.header-search__item');
86                let queryListBlock = target.closest('.header-search__list');
87                let historyBlock = target.closest('.header-search__history');
88
89                let query = target.getAttribute('data-value');
90                if (query) {
91                    self.deleteQueryFromSearchHistory(query);
92                    queryBlock.remove();
93                }
94
95                if (historyBlock && queryListBlock.childElementCount < 1) {
96                    historyBlock.remove();
97                }
98            });
99        });
100    }
101    
102    initAjaxHandlers() {
103        let self = this;
104        
105        let searchAllButton = document.getElementById('search-all');
106        if (searchAllButton) {
107            searchAllButton.addEventListener('click', function(event) {
108                event.preventDefault();
109                self.loaderStart();
110                self.addQueryToSearchHistory();
111            })
112        }
113    }
114
115    addQueryToSearchHistory() {
116        let self = this;
117
118        BX.ajax({
119            url: self.params.SEARCH_HISTORY_AJAX,
120            data: {
121                'type': 'add',
122                'query': self.input.value,
123            },
124            method: 'POST',
125            dataType: 'json',
126            onsuccess: function(response){
127                if (response && response.status !== 'success') {
128                    console.log('Add query to search history error!');
129                }
130                self.redirectToSearchPage();
131            },
132            onfailure: function(){
133                console.log('Request error!');
134            }
135        });
136    }
137
138    deleteQueryFromSearchHistory(query) {
139        let self = this;
140
141        BX.ajax({
142            url: self.params.SEARCH_HISTORY_AJAX,
143            data: {
144                'type': 'delete',
145                'query': query,
146            },
147            method: 'POST',
148            dataType: 'json',
149            onsuccess: function(response){
150                if (response && response.status !== 'success') {
151                    console.log('Delete query to search history error!');
152                }
153            },
154            onfailure: function(){
155                console.log('Request error!');
156            }
157        });
158    }
159
160    redirectToSearchPage() {
161        location.href = '/search/?q=' + this.input.value.trim().replace(' ', '%20');
162    }
163
164    onChange() {
165        let self = this;
166
167        if (self.processing) {
168            self.pending = true;
169            return;
170        }
171
172        clearTimeout(self.debounceTimer);
173
174        self.debounceTimer = setTimeout(() => {
175            self.loaderStart();
176
177            let query = self.input.value.trim();
178            if (self.cache[query] != null) {
179                self.showResult(self.cache[query]);
180                self.loaderEnd();
181            } else {
182                BX.ajax.post(
183                    self.params.AJAX_PAGE,
184                    {
185                        'ajax_call': 'y',
186                        'INPUT_ID': self.params.INPUT_ID,
187                        'l': self.params.MIN_QUERY_LEN,
188                        'q': query,
189                    },
190                    function(response) {
191                        self.cache[query] = response.trim();
192                        self.showResult(self.cache[query]);
193                        self.loaderEnd();
194
195                        if (self.pending) {
196                            self.pending = false;
197                            self.onChange();
198                        }
199                        
200                        self.initAjaxHandlers();
201                    },
202                );
203            }
204        }, 1000);
205    }
206
207    loaderStart() {
208        this.processing = true;
209        this.loader.classList.remove('hidden');
210        this.empty.classList.add('hidden');
211    }
212
213    loaderEnd() {
214        this.processing = false;
215        this.loader.classList.add('hidden');
216    }
217
218    showResult(html = '') {
219        this.hideAdditionalBlock();
220
221        this.resultContainer.innerHTML = html;
222
223        if (html.length > 0) {
224            this.empty.classList.add('hidden');
225        } else {
226            this.empty.classList.remove('hidden');
227        }
228    }
229
230    clearResult() {
231        this.showAdditionalBlocks();
232        this.resultContainer.innerHTML = '';
233    }
234
235    showAdditionalBlocks() {
236        document.querySelectorAll('.additional-block').forEach(function(block) {
237            block.classList.remove('hidden');
238        })
239    }
240
241    hideAdditionalBlock() {
242        document.querySelectorAll('.additional-block').forEach(function(block) {
243            block.classList.add('hidden');
244        })
245    }
246}

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.