PageSourceSearch

https://ichehol.ru/bitrix/templates/aspro_max/components/bitrix/search.title/mega_menu/script.js

js ichehol.ru collected 2026-10-06 15:25:30 UTC 10,832 bytes, 434 lines download raw bytes

1$(document).ready(function(){
2	var containerHTML = $('.title-search-input_mega_menu').detach();
3	$('#title-search_mega_menu').append(containerHTML);
4});
5
6function JCTitleSearch3(arParams)
7{
8	var _this = this;
9
10	this.arParams = {
11		'AJAX_PAGE': arParams.AJAX_PAGE,
12		'CONTAINER_ID': arParams.CONTAINER_ID,
13		'INPUT_ID': arParams.INPUT_ID,
14		'MIN_QUERY_LEN': parseInt(arParams.MIN_QUERY_LEN)
15	};
16	if(arParams.WAIT_IMAGE)
17		this.arParams.WAIT_IMAGE = arParams.WAIT_IMAGE;
18	if(arParams.MIN_QUERY_LEN <= 0)
19		arParams.MIN_QUERY_LEN = 1;
20
21	this.cache = [];
22	this.cache_key = null;
23
24	this.startText = '';
25	this.running = false;
26	this.needRunAgain = false;
27	this.currentRow = -1;
28	this.RESULT = null;
29	this.CONTAINER = null;
30	this.INPUT = null;
31	this.TYPE = null;
32	this.WAIT = null;
33
34	this.ShowResult = function(result)
35	{
36		if(BX.type.isString(result))
37		{
38			_this.RESULT.innerHTML = result;
39		}
40
41		_this.RESULT.style.display = _this.RESULT.innerHTML !== '' ? 'block' : 'none';
42		var pos = _this.adjustResultNode();
43
44		//adjust left column to be an outline
45		var res_pos;
46		var th;
47		var tbl = BX.findChild(_this.RESULT, {'tag':'table','class':'title-search-result'}, true);
48		if(tbl)
49		{
50			th = BX.findChild(tbl, {'tag':'th'}, true);
51		}
52		if(th)
53		{
54			var tbl_pos = BX.pos(tbl);
55			tbl_pos.width = tbl_pos.right - tbl_pos.left;
56
57			var th_pos = BX.pos(th);
58			th_pos.width = th_pos.right - th_pos.left;
59			th.style.width = th_pos.width + 'px';
60
61			_this.RESULT.style.width = (pos.width + th_pos.width) + 'px';
62
63			//Move table to left by width of the first column
64			_this.RESULT.style.left = (pos.left - th_pos.width - 1)+ 'px';
65
66			//Shrink table when it's too wide
67			if((tbl_pos.width - th_pos.width) > pos.width)
68				_this.RESULT.style.width = (pos.width + th_pos.width -1) + 'px';
69
70			//Check if table is too wide and shrink result div to it's width
71			tbl_pos = BX.pos(tbl);
72			res_pos = BX.pos(_this.RESULT);
73			if(res_pos.right > tbl_pos.right)
74			{
75				_this.RESULT.style.width = (tbl_pos.right - tbl_pos.left) + 'px';
76			}
77		}
78
79		var fade;
80		if(tbl) fade = BX.findChild(_this.RESULT, {'class':'title-search-fader'}, true);
81		if(fade && th)
82		{
83			res_pos = BX.pos(_this.RESULT);
84			fade.style.left = (res_pos.right - res_pos.left - 18) + 'px';
85			fade.style.width = 18 + 'px';
86			fade.style.top = 0 + 'px';
87			fade.style.height = (res_pos.bottom - res_pos.top) + 'px';
88			fade.style.display = 'block';
89		}
90
91	};
92
93	this.onKeyPress = function(keyCode)
94	{
95		var tbl = BX.findChild(_this.RESULT, {'tag':'table','class':'title-search-result'}, true);
96		if(!tbl)
97			return false;
98
99		var i;
100		var cnt = tbl.rows.length;
101
102		switch (keyCode)
103		{
104		case 27: // escape key - close search div
105			_this.RESULT.style.display = 'none';
106			_this.currentRow = -1;
107			_this.UnSelectAll();
108		return true;
109
110		case 40: // down key - navigate down on search results
111			if(_this.RESULT.style.display == 'none')
112				_this.RESULT.style.display = 'block';
113
114			var first = -1;
115			for(i = 0; i < cnt; i++)
116			{
117				if(!BX.findChild(tbl.rows[i], {'class':'title-search-separator'}, true))
118				{
119					if(first == -1)
120						first = i;
121
122					if(_this.currentRow < i)
123					{
124						_this.currentRow = i;
125						break;
126					}
127					else if(tbl.rows[i].className == 'title-search-selected')
128					{
129						tbl.rows[i].className = '';
130					}
131				}
132			}
133
134			if(i == cnt && _this.currentRow != i)
135				_this.currentRow = first;
136
137			tbl.rows[_this.currentRow].className = 'title-search-selected';
138		return true;
139
140		case 38: // up key - navigate up on search results
141			if(_this.RESULT.style.display == 'none')
142				_this.RESULT.style.display = 'block';
143
144			var last = -1;
145			for(i = cnt-1; i >= 0; i--)
146			{
147				if(!BX.findChild(tbl.rows[i], {'class':'title-search-separator'}, true))
148				{
149					if(last == -1)
150						last = i;
151
152					if(_this.currentRow > i)
153					{
154						_this.currentRow = i;
155						break;
156					}
157					else if(tbl.rows[i].className == 'title-search-selected')
158					{
159						tbl.rows[i].className = '';
160					}
161				}
162			}
163
164			if(i < 0 && _this.currentRow != i)
165				_this.currentRow = last;
166
167			tbl.rows[_this.currentRow].className = 'title-search-selected';
168		return true;
169
170		case 13: // enter key - choose current search result
171			if(_this.RESULT.style.display == 'block')
172			{
173				for(i = 0; i < cnt; i++)
174				{
175					if(_this.currentRow == i)
176					{
177						if(!BX.findChild(tbl.rows[i], {'class':'title-search-separator'}, true))
178						{
179							var a = BX.findChild(tbl.rows[i], {'tag':'a'}, true);
180							if(a)
181							{
182								window.location = a.href;
183								return true;
184							}
185						}
186					}
187				}
188			}
189		return false;
190		}
191
192		return false;
193	};
194
195	this.onTimeout = function()
196	{
197		_this.onChange(function(){
198			setTimeout(_this.onTimeout, 500);
199		});
200	};
201
202	this.onChange = function(callback)
203	{
204		if (_this.running) {
205			_this.needRunAgain = true;
206			return;
207		}
208		_this.running = true;
209
210		let type = 'catalog';
211		if (this.TYPE) {
212			type = this.TYPE.value;
213		}
214
215		if(
216			(
217				_this.INPUT.value != _this.oldValue
218				&& _this.INPUT.value != _this.startText
219			)
220			|| type != _this.oldType
221		){
222			_this.oldValue = _this.INPUT.value;
223			_this.oldType = type;
224
225			if(_this.INPUT.value.length >= _this.arParams.MIN_QUERY_LEN)
226			{
227				_this.cache_key = _this.arParams.INPUT_ID + '|' + _this.INPUT.value + '|' + type;
228				if(_this.cache[_this.cache_key] == null)
229				{
230					if(_this.WAIT)
231					{
232						var pos = BX.pos(_this.INPUT);
233						var height = (pos.bottom - pos.top)-2;
234						_this.WAIT.style.top = (pos.top+1) + 'px';
235						_this.WAIT.style.height = height + 'px';
236						_this.WAIT.style.width = height + 'px';
237						_this.WAIT.style.left = (pos.right - height + 2) + 'px';
238						_this.WAIT.style.display = 'block';
239					}
240
241					BX.ajax.post(
242						_this.arParams.AJAX_PAGE,
243						{
244							'ajax_call':'y',
245							'INPUT_ID':_this.arParams.INPUT_ID,
246							'q':_this.INPUT.value,
247							'l':_this.arParams.MIN_QUERY_LEN,
248							'type': type,
249						},
250						function(result)
251						{
252							_this.cache[_this.cache_key] = result;
253							_this.ShowResult(result);
254							_this.currentRow = -1;
255							_this.EnableMouseEvents();
256							if(_this.WAIT)
257								_this.WAIT.style.display = 'none';
258							if (!!callback)
259								callback();
260							_this.running = false;
261
262							if(_this.needRunAgain){
263								_this.needRunAgain = false;
264								_this.onChange(callback);
265							}
266						}
267					);
268					return;
269				}
270				else
271				{
272					_this.ShowResult(_this.cache[_this.cache_key]);
273					_this.currentRow = -1;
274					_this.EnableMouseEvents();
275				}
276			}
277			else
278			{
279				_this.RESULT.style.display = 'none';
280				_this.currentRow = -1;
281				_this.UnSelectAll();
282			}
283		}
284		if (!!callback)
285			callback();
286		_this.running = false;
287	};
288
289	this.UnSelectAll = function()
290	{
291		var tbl = BX.findChild(_this.RESULT, {'tag':'table','class':'title-search-result'}, true);
292		if(tbl)
293		{
294			var cnt = tbl.rows.length;
295			for(var i = 0; i < cnt; i++)
296				tbl.rows[i].className = '';
297		}
298	};
299
300	this.EnableMouseEvents = function()
301	{
302		var tbl = BX.findChild(_this.RESULT, {'tag':'table','class':'title-search-result'}, true);
303		if(tbl)
304		{
305			var cnt = tbl.rows.length;
306			for(var i = 0; i < cnt; i++)
307				if(!BX.findChild(tbl.rows[i], {'class':'title-search-separator'}, true))
308				{
309					tbl.rows[i].id = 'row_' + i;
310					tbl.rows[i].onmouseover = function (e) {
311						if(_this.currentRow != this.id.substr(4))
312						{
313							_this.UnSelectAll();
314							this.className = 'title-search-selected';
315							_this.currentRow = this.id.substr(4);
316						}
317					};
318					tbl.rows[i].onmouseout = function (e) {
319						this.className = '';
320						_this.currentRow = -1;
321					};
322				}
323		}
324	};
325
326	this.onFocusLost = function(hide)
327	{
328		setTimeout(function(){_this.RESULT.style.display = 'none';}, 250);
329		//_this.RESULT.style.display = 'none';
330	};
331
332	this.onFocusGain = function()
333	{
334		if(_this.RESULT.innerHTML.length)
335			_this.ShowResult();
336	};
337
338	this.onKeyDown = function(e)
339	{
340		if(!e)
341			e = window.event;
342
343		if (_this.RESULT.style.display == 'block')
344		{
345			if(_this.onKeyPress(e.keyCode))
346				return BX.PreventDefault(e);
347		}
348		
349		$('.title-search-result.'+_this.arParams.INPUT_ID).removeClass('closed');
350	};
351
352	this.adjustResultNode = function()
353	{
354		var pos, pos_input;
355		var fixedParent = BX.findParent(_this.CONTAINER, BX.is_fixed);
356		/*if(!!fixedParent)
357		{
358			_this.RESULT.style.position = 'fixed';
359			_this.RESULT.style.zIndex = BX.style(fixedParent, 'z-index') + 2;
360			pos = BX.pos(_this.CONTAINER, true);
361		}
362		else
363		{*/
364			_this.RESULT.style.position = 'absolute';
365			pos = BX.pos(_this.CONTAINER, true);
366		//}
367		pos_input = BX.pos(_this.INPUT);
368
369		pos.width = pos.right - pos.left;
370		_this.RESULT.style.top = (pos.bottom + 2) + 'px';
371		//_this.RESULT.style.left = pos_input.left + 'px';
372		_this.RESULT.style.left = 0 + 'px';
373
374		if($(_this.INPUT).closest('.inline-search-block.with-close').length)
375			_this.RESULT.style.width = pos_input.width + 'px';
376		else
377			_this.RESULT.style.width = pos.width + 'px';
378		return pos;
379	};
380
381	this._onContainerLayoutChange = function()
382	{
383		if(_this.RESULT.style.display !== "none" && _this.RESULT.innerHTML !== '')
384		{
385			_this.adjustResultNode();
386		}
387	};
388	this.Init = function()
389	{
390		this.CONTAINER = document.getElementById(this.arParams.CONTAINER_ID);
391		BX.addCustomEvent(this.CONTAINER, "OnNodeLayoutChange", this._onContainerLayoutChange);
392
393		this.RESULT = document.body.appendChild(document.createElement("DIV"));
394
395		this.RESULT.className = 'title-search-result '+this.arParams.INPUT_ID;
396		this.INPUT = document.getElementById(this.arParams.INPUT_ID);
397		this.startText = this.oldValue = this.INPUT.value;
398		BX.bind(this.INPUT, 'focus', function() {_this.onFocusGain()});
399		BX.bind(this.INPUT, 'blur', function() {
400			if (window.matchMedia("(min-width: 993px)").matches) {
401				setTimeout(function(){
402					if(!$(_this.INPUT).closest('form').find('.dropdown-select.searchtype .dropdown-select__title.opened').length){
403						_this.onFocusLost();
404					}
405				}, 100);
406			}
407		});
408
409		this.TYPE = this.CONTAINER ? this.CONTAINER.querySelector('.dropdown-select.searchtype input[name="type"]') : null;
410
411		if(BX.browser.IsSafari() || BX.browser.IsIE())
412			this.INPUT.onkeydown = this.onKeyDown;
413		else
414			this.INPUT.onkeypress = this.onKeyDown;
415
416		if(this.arParams.WAIT_IMAGE)
417		{
418			this.WAIT = document.body.appendChild(document.createElement("DIV"));
419			this.WAIT.style.backgroundImage = "url('" + this.arParams.WAIT_IMAGE + "')";
420			if(!BX.browser.IsIE())
421				this.WAIT.style.backgroundRepeat = 'none';
422			this.WAIT.style.display = 'none';
423			this.WAIT.style.position = 'absolute';
424			this.WAIT.style.zIndex = '1100';
425		}
426
427		BX.bind(this.INPUT, 'bxchange', function() {_this.onChange()});
428
429		if (this.TYPE) {
430			BX.bind(this.TYPE, 'change', function() {_this.onChange()});
431		}
432	};
433	BX.ready(function (){_this.Init(arParams)});
434}

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.