PageSourceSearch

https://ovdi.ru/bitrix/components/bitrix/sale.basket.basket/templates/.default/js/filter.js

js ovdi.ru collected 2026-09-28 11:09:50 UTC 14,092 bytes, 588 lines download raw bytes

1;(function(){
2	'use strict';
3
4	BX.namespace('BX.Sale.BasketFilter');
5
6	BX.Sale.BasketFilter = function(component)
7	{
8		this.component = component;
9
10		this.activeFilterMode = false;
11		this.filterTimer = null;
12		this.mouseOverClearFilter = false;
13
14		this.realShownItems = [];
15		this.realSortedItems = [];
16		this.realScrollTop = 0;
17
18		this.lastShownItemsHash = '';
19		this.currentFilter = {
20			query: '',
21			similarHash: '',
22			warning: false,
23			notAvailable: false,
24			delayed: false
25		};
26
27		if (this.component.useItemsFilter)
28		{
29			this.bindEvents();
30		}
31	};
32
33	BX.Sale.BasketFilter.prototype.bindEvents = function()
34	{
35		var entity;
36		var filterNode = this.component.getEntity(
37			this.component.getCacheNode(this.component.ids.itemListWrapper),
38			'basket-filter'
39		);
40
41		entity = this.component.getEntity(filterNode, 'basket-filter-input');
42		if (BX.type.isDomNode(entity))
43		{
44			BX.bind(entity, 'focus', function() {
45				filterNode.style.flex = 3;
46			});
47			BX.bind(entity, 'blur', BX.delegate(function() {
48				if (!this.mouseOverClearFilter)
49				{
50					filterNode.style.flex = '';
51				}
52			}, this));
53
54			BX.bind(entity, 'keyup', BX.proxy(this.onFilterInput, this));
55			BX.bind(entity, 'cut', BX.proxy(this.onFilterInput, this));
56			BX.bind(entity, 'paste', BX.proxy(this.onFilterInput, this));
57		}
58
59		entity = this.component.getEntity(filterNode, 'basket-filter-clear-btn');
60		if (BX.type.isDomNode(entity))
61		{
62			BX.bind(entity, 'mouseenter', BX.delegate(function() {
63				this.mouseOverClearFilter = true;
64			}, this));
65			BX.bind(entity, 'mouseout', BX.delegate(function() {
66				this.mouseOverClearFilter = false;
67			}, this));
68			BX.bind(entity, 'click', BX.delegate(function() {
69				if (!this.filterInputEmpty())
70				{
71					this.clearFilterInput();
72					this.onFilterChange();
73				}
74
75				filterNode.style.flex = '';
76			}, this));
77		}
78	};
79
80	BX.Sale.BasketFilter.prototype.isActive = function()
81	{
82		return this.activeFilterMode;
83	};
84
85	BX.Sale.BasketFilter.prototype.showFilterByName = function(name)
86	{
87		if (!name)
88			return;
89
90		switch (name)
91		{
92			case 'not-available':
93				this.showNotAvailableItemsFilter();
94				break;
95			case 'delayed':
96				this.showDelayItemsFilter();
97				break;
98			case 'warning':
99				this.showWarningItemsFilter();
100				break;
101			case 'similar':
102				this.showSimilarItemsFilter();
103				break;
104			case 'all':
105			default:
106				this.clearAllFiltersExcept([]);
107				this.onFilterChange();
108		}
109	};
110
111	BX.Sale.BasketFilter.prototype.onFilterInput = function()
112	{
113		var value = BX.type.isDomNode(BX.proxy_context) ? BX.util.trim(BX.proxy_context.value).toLowerCase() : '';
114
115		if (this.currentFilter.query !== value)
116		{
117			this.currentFilter.query = value;
118
119			this.onFilterChange();
120		}
121	};
122
123	BX.Sale.BasketFilter.prototype.clearAllFiltersExcept = function(names)
124	{
125		if (!names || !BX.type.isArray(names))
126			return;
127
128		!BX.util.in_array('input', names) && this.clearFilterInput();
129		!BX.util.in_array('warning', names) && this.clearWarningItemsFilter();
130		!BX.util.in_array('delayed', names) && this.clearDelayItemsFilter();
131		!BX.util.in_array('not-available', names) && this.clearNotAvailableItemsFilter();
132
133		if (!BX.util.in_array('similar', names))
134		{
135			this.clearSimilarItemsFilter();
136			this.component.showSimilarCount(false);
137		}
138	};
139
140	BX.Sale.BasketFilter.prototype.filterInputEmpty = function()
141	{
142		return this.currentFilter.query.length === 0;
143	};
144
145	BX.Sale.BasketFilter.prototype.clearFilterInput = function()
146	{
147		this.currentFilter.query = '';
148
149		var input = this.component.getEntity(
150			this.component.getCacheNode(this.component.ids.itemListWrapper),
151			'basket-filter-input'
152		);
153		if (BX.type.isDomNode(input))
154		{
155			input.value = '';
156		}
157	};
158
159	BX.Sale.BasketFilter.prototype.addWarningItemsFilter = function()
160	{
161		this.currentFilter.warning = true;
162	};
163
164	BX.Sale.BasketFilter.prototype.clearWarningItemsFilter = function()
165	{
166		this.currentFilter.warning = false;
167	};
168
169	BX.Sale.BasketFilter.prototype.showWarningItemsFilter = function()
170	{
171		if (!this.currentFilter.warning)
172		{
173			this.clearAllFiltersExcept(['warning']);
174			this.addWarningItemsFilter();
175			this.onFilterChange();
176		}
177	};
178
179	BX.Sale.BasketFilter.prototype.addDelayItemsFilter = function()
180	{
181		this.currentFilter.delayed = true;
182	};
183
184	BX.Sale.BasketFilter.prototype.clearDelayItemsFilter = function()
185	{
186		this.currentFilter.delayed = false;
187	};
188
189	BX.Sale.BasketFilter.prototype.showDelayItemsFilter = function()
190	{
191		if (!this.currentFilter.delayed)
192		{
193			this.clearAllFiltersExcept(['delayed']);
194			this.addDelayItemsFilter();
195			this.onFilterChange();
196		}
197	};
198
199	BX.Sale.BasketFilter.prototype.addNotAvailableItemsFilter = function()
200	{
201		this.currentFilter.notAvailable = true;
202	};
203
204	BX.Sale.BasketFilter.prototype.clearNotAvailableItemsFilter = function()
205	{
206		this.currentFilter.notAvailable = false;
207	};
208
209	BX.Sale.BasketFilter.prototype.showNotAvailableItemsFilter = function()
210	{
211		if (!this.currentFilter.notAvailable)
212		{
213			this.clearAllFiltersExcept(['not-available']);
214			this.addNotAvailableItemsFilter();
215			this.onFilterChange();
216		}
217	};
218
219	BX.Sale.BasketFilter.prototype.addSimilarItemsFilter = function(item)
220	{
221		this.currentFilter.similarHash = item.HASH;
222	};
223
224	BX.Sale.BasketFilter.prototype.clearSimilarItemsFilter = function()
225	{
226		this.currentFilter.similarHash = '';
227	};
228
229	BX.Sale.BasketFilter.prototype.showSimilarItemsFilter = function()
230	{
231		var item = this.component.getItemDataByTarget(BX.proxy_context);
232
233		if (this.currentFilter.similarHash !== item.HASH)
234		{
235			this.clearAllFiltersExcept(['similar']);
236			this.addSimilarItemsFilter(item);
237			this.onFilterChange();
238		}
239	};
240
241	BX.Sale.BasketFilter.prototype.getTimeoutDuration = function()
242	{
243		return this.component.duration.filterTimer;
244	};
245
246	BX.Sale.BasketFilter.prototype.onFilterChange = function()
247	{
248		this.component.showItemsOverlay();
249
250		if (
251			this.currentFilter.query.length
252			|| this.currentFilter.similarHash.length
253			|| this.currentFilter.warning
254			|| this.currentFilter.notAvailable
255			|| this.currentFilter.delayed
256		)
257		{
258			clearTimeout(this.filterTimer);
259			this.filterTimer = setTimeout(BX.proxy(this.enableFilterMode, this), this.getTimeoutDuration());
260		}
261		else
262		{
263			this.disableFilterMode();
264		}
265	};
266
267	BX.Sale.BasketFilter.prototype.enableFilterMode = function()
268	{
269		var foundItemsHash;
270
271		if (!this.activeFilterMode)
272		{
273			this.activeFilterMode = true;
274			this.realShownItems = BX.util.array_values(this.component.shownItems);
275			this.realSortedItems = BX.util.array_values(this.component.sortedItems);
276			this.realScrollTop = this.component.getDocumentScrollTop();
277		}
278
279		this.component.scrollToFirstItem();
280
281		this.component.sortedItems = this.searchItems();
282
283		foundItemsHash = JSON.stringify(this.component.sortedItems);
284
285		if (this.lastShownItemsHash !== foundItemsHash)
286		{
287			this.lastShownItemsHash = foundItemsHash;
288
289			this.component.deleteBasketItems(BX.util.array_values(this.component.shownItems), false);
290
291			if (this.component.sortedItems.length)
292			{
293				this.component.initializeBasketItems();
294				this.hideEmptyFilterResult();
295			}
296			else
297			{
298				this.showEmptyFilterResult();
299			}
300
301			if (this.currentFilter.similarHash.length)
302			{
303				this.component.showSimilarCount(true);
304			}
305		}
306		else
307		{
308			this.highlightFoundItems();
309		}
310
311		this.component.hideItemsOverlay();
312	};
313
314	BX.Sale.BasketFilter.prototype.disableFilterMode = function()
315	{
316		clearTimeout(this.filterTimer);
317		this.lastShownItemsHash = '';
318
319		if (this.activeFilterMode)
320		{
321			this.activeFilterMode = false;
322			this.component.sortedItems = BX.util.array_values(this.realSortedItems);
323
324			this.component.deleteBasketItems(BX.util.array_values(this.component.shownItems), false);
325			this.hideEmptyFilterResult();
326
327			this.component.editBasketItems(BX.util.array_values(this.realShownItems));
328			window.scrollTo(0, this.realScrollTop);
329		}
330
331		this.component.hideItemsOverlay();
332	};
333
334	BX.Sale.BasketFilter.prototype.searchItems = function()
335	{
336		var items = [];
337
338		for (var i = 0; i < this.realSortedItems.length; i++)
339		{
340			var item = this.component.items[this.realSortedItems[i]];
341
342			if (item && this.searchItemMatch(item))
343			{
344				items.push(item.ID);
345			}
346		}
347
348		return items;
349	};
350
351	BX.Sale.BasketFilter.prototype.highlightFoundItems = function()
352	{
353		if (!this.activeFilterMode)
354			return;
355
356		for (var i in this.component.shownItems)
357		{
358			if (this.component.shownItems.hasOwnProperty(i))
359			{
360				this.highlightSearchMatch(this.component.items[this.component.shownItems[i]]);
361			}
362		}
363	};
364
365	BX.Sale.BasketFilter.prototype.searchItemMatch = function(item)
366	{
367		var match = false,
368			found = false;
369
370		if (this.currentFilter.notAvailable)
371		{
372			found = !!item.NOT_AVAILABLE;
373			if (!found)
374			{
375				return match;
376			}
377		}
378		else if (this.currentFilter.delayed)
379		{
380			found = !!item.DELAYED;
381			if (!found)
382			{
383				return match;
384			}
385		}
386		else if (this.currentFilter.warning)
387		{
388			found = BX.util.in_array(item.ID, this.component.warningItems);
389			if (!found)
390			{
391				return match;
392			}
393		}
394		else if (BX.type.isNotEmptyString(this.currentFilter.similarHash))
395		{
396			found = this.currentFilter.similarHash === item.HASH;
397			if (!found)
398			{
399				return match;
400			}
401		}
402
403		if (BX.type.isNotEmptyString(this.currentFilter.query))
404		{
405			if (item.NAME.toLowerCase().indexOf(this.currentFilter.query) !== -1)
406			{
407				match = 'NAME';
408			}
409
410			if (!match)
411			{
412				var floatValue = parseFloat(this.currentFilter.query);
413				if (!isNaN(floatValue))
414				{
415					if (parseFloat(item.PRICE) === floatValue)
416					{
417						match = 'PRICE';
418					}
419					else if (parseFloat(item.SUM_PRICE) === floatValue)
420					{
421						match = 'SUM_PRICE';
422					}
423				}
424			}
425
426			if (!match && this.currentFilter.query.length >= 3)
427			{
428				if (item.PRICE_FORMATED.toLowerCase().indexOf(this.currentFilter.query) !== -1)
429				{
430					match = 'PRICE';
431				}
432				else if (item.SUM_PRICE_FORMATED.toLowerCase().indexOf(this.currentFilter.query) !== -1)
433				{
434					match = 'SUM_PRICE';
435				}
436			}
437
438			var k, lcValue;
439
440			if (!match && item.PROPS.length)
441			{
442				for (k in item.PROPS)
443				{
444					if (item.PROPS.hasOwnProperty(k) && BX.type.isNotEmptyString(item.PROPS[k].VALUE))
445					{
446						lcValue = item.PROPS[k].VALUE.toLowerCase();
447
448						if (
449							lcValue === this.currentFilter.query
450							|| (this.currentFilter.query.length >= 3 && lcValue.indexOf(this.currentFilter.query) !== -1)
451						)
452						{
453							match = 'PROPS';
454							break;
455						}
456					}
457				}
458			}
459
460			if (!match && item.COLUMN_LIST.length)
461			{
462				for (k in item.COLUMN_LIST)
463				{
464					if (item.COLUMN_LIST.hasOwnProperty(k) && BX.type.isNotEmptyString(item.COLUMN_LIST[k].VALUE))
465					{
466						lcValue = item.COLUMN_LIST[k].VALUE.toLowerCase();
467
468						if (
469							lcValue === this.currentFilter.query
470							|| (this.currentFilter.query.length >= 3 && lcValue.indexOf(this.currentFilter.query) !== -1)
471						)
472						{
473							match = 'COLUMNS';
474							break;
475						}
476					}
477				}
478			}
479		}
480		else if (found)
481		{
482			match = true;
483		}
484
485		return match;
486	};
487
488	BX.Sale.BasketFilter.prototype.highlightSearchMatch = function(itemData)
489	{
490		var searchMatch = this.searchItemMatch(itemData);
491
492		if (searchMatch)
493		{
494			var entity, i, k, code;
495
496			switch (searchMatch)
497			{
498				case 'NAME':
499					entity = this.component.getEntity(BX(this.component.ids.item + itemData.ID), 'basket-item-name');
500					if (BX.type.isDomNode(entity))
501					{
502						entity.innerHTML = itemData.NAME.replace(
503							new RegExp('(.*)(' + this.currentFilter.query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + ')(.*)', 'gi'),
504							function (full, match1 , match2, match3)
505							{
506								return BX.util.htmlspecialchars(match1)
507									+ '<span class="basket-item-highlighted">'
508									+ BX.util.htmlspecialchars(match2)
509									+ '</span>' + BX.util.htmlspecialchars(match3);
510							}
511						);
512					}
513					break;
514				case 'PRICE':
515					entity = BX(this.component.ids.price + itemData.ID);
516					BX.addClass(entity, 'basket-item-highlighted');
517					break;
518				case 'SUM_PRICE':
519					entity = BX(this.component.ids.sumPrice + itemData.ID);
520					BX.addClass(entity, 'basket-item-highlighted');
521					break;
522				case 'PROPS':
523					entity = this.component.getEntities(BX(this.component.ids.item + itemData.ID), 'basket-item-property-value');
524
525					for (i = 0; i < entity.length; i++)
526					{
527						code = entity[i].getAttribute('data-property-code');
528
529						for (k in itemData.PROPS)
530						{
531							if (itemData.PROPS.hasOwnProperty(k) && itemData.PROPS[k].CODE === code)
532							{
533								entity[i].innerHTML = itemData.PROPS[k].VALUE.replace(
534									new RegExp('(' + this.currentFilter.query + ')', 'gi'),
535									'<span class="basket-item-highlighted">$1</span>'
536								);
537							}
538						}
539					}
540					break;
541				case 'COLUMNS':
542					entity = this.component.getEntities(BX(this.component.ids.item + itemData.ID), 'basket-item-property-column-value');
543
544					for (i = 0; i < entity.length; i++)
545					{
546						code = entity[i].getAttribute('data-column-property-code');
547
548						for (k in itemData.COLUMN_LIST)
549						{
550							if (itemData.COLUMN_LIST.hasOwnProperty(k) && itemData.COLUMN_LIST[k].CODE === code)
551							{
552								entity[i].innerHTML = itemData.COLUMN_LIST[k].VALUE.replace(
553									new RegExp('(' + this.currentFilter.query + ')', 'gi'),
554									'<span class="basket-item-highlighted">$1</span>'
555								);
556							}
557						}
558					}
559					break;
560			}
561		}
562	};
563
564	BX.Sale.BasketFilter.prototype.showEmptyFilterResult = function()
565	{
566		var itemListNode = this.component.getCacheNode(this.component.ids.itemList);
567
568		if (BX.type.isDomNode(itemListNode) && itemListNode.clientHeight >= 500)
569		{
570			var emptyResultNode = this.component.getCacheNode(this.component.ids.itemListEmptyResult);
571
572			if (BX.type.isDomNode(emptyResultNode))
573			{
574				emptyResultNode.style.display = '';
575			}
576		}
577	};
578
579	BX.Sale.BasketFilter.prototype.hideEmptyFilterResult = function()
580	{
581		var emptyResultNode = this.component.getCacheNode(this.component.ids.itemListEmptyResult);
582
583		if (BX.type.isDomNode(emptyResultNode))
584		{
585			emptyResultNode.style.display = 'none';
586		}
587	};
588})();

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.