PageSourceSearch

https://poly-max.com/local/templates/polymax_copy/components/bitrix/sale.basket.basket/plmx/js/filter.js

js poly-max.com collected 2026-09-29 15:53:38 UTC 15,585 bytes, 522 lines download raw bytes

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

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.