1(function (_, $) { 2 var base_url; 3 var ajax_ids; 4 var no_trigger = false; 5 var changed_objects = []; 6 var filtered_tables_state = {}; 7 var dropdowns_state = {}; 8 var cursorState = {}; 9 var ajax_promise; 10 var timer; 11 var timerStatusBox; 12 var lastSelectedElms = {}; 13 var HASH_SEPARATOR = '_'; 14 var HASH_FEATURE_SEPARATOR = '-'; 15 var REQUEST_DELAY = 1000; 16 var HIDE_DELAY = 5000; 17 (function ($) { 18 function generateHash(container) { 19 var features = {}; 20 var hash = []; 21 container.find('input.cm-product-filters-checkbox:checked').each(function () { 22 var elm = $(this); 23 if (!features[elm.data('caFilterId')]) { 24 features[elm.data('caFilterId')] = []; 25 } 26 features[elm.data('caFilterId')].push(elm.val()); 27 }); 28 for (var k in features) { 29 hash.push(k + HASH_FEATURE_SEPARATOR + features[k].join(HASH_FEATURE_SEPARATOR)); 30 } 31 return hash.join(HASH_SEPARATOR); 32 } 33 function resetFilters(obj) { 34 obj.prop('checked', !obj.prop('checked')); 35 if (obj.data('prevVal')) { 36 no_trigger = true; 37 var vals = obj.data('prevVal').split('-'); 38 var sli = obj.parent().find('.cm-range-slider'); 39 if (sli.length) { 40 sli.slider('values', [vals[0], vals[1]]); 41 sli.slider('option', 'slide').call(sli, {}, { 42 values: [vals[0], vals[1]] 43 }); // that's so dirty, but it works 44 } 45 var da = obj.parent().find('.cm-date-range'); 46 if (da.length) { 47 da.daterangepicker({ 48 startDate: vals[0], 49 endDate: vals[1] 50 }); 51 } 52 no_trigger = false; 53 } 54 } 55 function getProducts(url, obj, objs, container) { 56 if (ajax_ids) { 57 loadProducts(url, obj, objs, container); 58 } else { 59 $.redirect(url); 60 } 61 return false; 62 } 63 function loadProducts(url, obj, objs, container) { 64 saveFilteredTablesState(container); 65 saveDropdownsState(container); 66 saveCursorState(); 67 ajax_promise = $.ceAjax('request', url, { 68 result_ids: ajax_ids, 69 full_render: true, 70 save_history: true, 71 get_promise: true, 72 hidden: true, 73 caching: false, 74 obj: obj 75 }); 76 ajax_promise.done(function (response) { 77 moveScrollToLastPosition(container); 78 if (response.products_found_message) { 79 var $checkboxContainer = $('#' + obj.attr('id')).closest('.cm-product-filters-checkbox-container'); 80 showTooltip($checkboxContainer, response.products_found_message); 81 } 82 changed_objects = []; 83 setVisibilityResetFilters(container); 84 }); 85 } 86 function moveScrollToLastPosition($container) { 87 if ($container && $container.hasClass('cm-filter-table-no-scroll')) { 88 return; 89 } 90 for (const [key, scrollTop] of Object.entries(lastSelectedElms)) { 91 let $variantList = $('#' + key); 92 if (!$variantList.length || $variantList.get(0).scrollHeight <= $variantList.get(0).clientHeight) { 93 continue; 94 } 95 $variantList.scrollTop(scrollTop); 96 } 97 } 98 function saveDropdownsState($container) { 99 dropdowns_state = {}; 100 $container.find('.cm-horizontal-filters-content').each(function () { 101 var $elem = $(this); 102 dropdowns_state[$elem.attr('id')] = { 103 open: $elem.is(':visible') 104 }; 105 }); 106 } 107 function restoreDropdownsState($container) { 108 $container.find('.cm-horizontal-filters-content').each(function () { 109 var $elem = $(this), 110 id = $elem.attr('id'); 111 if (dropdowns_state[id] && dropdowns_state[id].open) { 112 $elem.removeClass('hidden'); 113 $('#sw_' + id).addClass('open'); 114 delete dropdowns_state[id]; 115 } 116 }); 117 } 118 function restoreVariantsState($productFilters) { 119 $('.cm-save-state', $productFilters).each(function () { 120 var $elem = $(this); 121 var id = $elem.attr('id'); 122 var prefix = 'sw_'; 123 if (!id.startsWith(prefix)) { 124 return; 125 } 126 var combination_id = id.substr(prefix.length); 127 if (!$.cookie.get(combination_id) || $elem.hasClass('cm-ss-reverse') && !$elem.hasClass('open')) { 128 return; 129 } 130 $.toggleCombination($elem); 131 }); 132 } 133 function saveFilteredTablesState($container) { 134 filtered_tables_state = {}; 135 $container.find('.cm-filter-table').each(function () { 136 var $elem = $(this), 137 $input = $('#' + $elem.data('caInputId')); 138 filtered_tables_state[$elem.attr('id')] = { 139 top: $elem.scrollTop(), 140 input_value: $input.val() 141 }; 142 }); 143 } 144 function restoreFilteredTablesState($container) { 145 $container.find('.cm-filter-table').each(function () { 146 var $elem = $(this), 147 id = $elem.attr('id'); 148 if (filtered_tables_state[id]) { 149 $elem.scrollTop(filtered_tables_state[id].top); 150 $elem.data('caInputValue', filtered_tables_state[id].input_value); 151 $elem.data('caScrollTop', filtered_tables_state[id].top); 152 delete filtered_tables_state[id]; 153 } 154 }); 155 } 156 function saveCursorState() { 157 cursorState = {};
158 var $focused = $(':focus'); 159 if (!$focused.length) { 160 return; 161 } 162 cursorState.id = $focused.attr('id'); 163 cursorState.type = $focused.attr('type'); 164 if (cursorState.type === 'text') { 165 cursorState.val = $focused.val(); 166 cursorState.selectionStart = $focused[0].selectionStart; 167 cursorState.selectionEnd = $focused[0].selectionEnd; 168 } 169 } 170 function restoreCursorState() { 171 if (!cursorState.id) { 172 return; 173 } 174 var $activeElem = $('#' + cursorState.id); 175 $activeElem.focus(); 176 if (cursorState.type !== 'text') { 177 return; 178 } 179 var activeElem = $activeElem[0]; 180 if ($activeElem.val() === cursorState.val) { 181 activeElem.setSelectionRange(cursorState.selectionStart, cursorState.selectionEnd); 182 } else { 183 activeElem.selectionStart = activeElem.selectionEnd = activeElem.value.length; 184 } 185 } 186 function setVisibilityResetFilters($filters) { 187 var $wrapperFilter = $filters.find('[data-ca-product-filters="wrapper"]'); 188 var $toolsFilter = $filters.find('[data-ca-product-filters="tools"]'); 189 if ($wrapperFilter.data('caProductFiltersStatus') === 'active') { 190 $toolsFilter.removeClass('hidden'); 191 } else { 192 $toolsFilter.addClass('hidden'); 193 } 194 } 195 function abortRequest() { 196 if (ajax_promise) { 197 ajax_promise.abort(); 198 } 199 clearTimeout(timer); 200 clearTimeout(timerStatusBox); 201 $.toggleStatusBox('hide'); 202 } 203 function setHandler() { 204 $(_.doc).on('click', '.ty-product-filters__reset-button', function () { 205 lastSelectedElms = {}; 206 }); 207 $(_.doc).on('click', '.ty-product-filters__block--variants .ty-reset-filters', function () { 208 let $parent = $(this).closest('.ty-product-filters__block'), 209 $variantsList = $parent.find('.ty-product-filters__variants'); 210 if ($variantsList.length) { 211 let idVariantList = $variantsList.attr('id'); 212 delete lastSelectedElms[idVariantList]; 213 } 214 }); 215 $(_.doc).on('change', '.cm-product-filters-checkbox:enabled', function () { 216 if (no_trigger) { 217 return; 218 } 219 if (ajax_promise) { 220 ajax_promise.abort(); 221 } 222 var $self = $(this), 223 $parent = $self.closest('.cm-filter-table'), 224 variantListId = $parent.attr('id'); 225 changed_objects.push($self); 226 lastSelectedElms[variantListId] = $parent.scrollTop(); 227 clearTimeout(timer); 228 $.toggleStatusBox('show', { 229 show_overlay: false 230 }); 231 timer = setTimeout(function () { 232 prepareGetProducts.apply($self); 233 }, REQUEST_DELAY); 234 }); 235 $(_.doc).on('ce:combination:switch', '.cm-product-filters .cm-combination', function (event, container, flag) { 236 if (!flag) { 237 return; 238 } 239 var $tooltip = $(container).find('[data-ce-tooltip="true"]'); 240 if ($tooltip.data('tooltip')) { 241 $tooltip.data('tooltip').getTip().remove(); 242 $tooltip.remove(); 243 ; 244 } 245 }); 246 } 247 function prepareGetProducts() { 248 var self = $(this); 249 var container = self.parents('.cm-product-filters'); 250 return getProducts($.attachToUrl(base_url, 'features_hash=' + generateHash(container)), self, changed_objects, container); 251 } 252 function showTooltip($container, message) { 253 if (!$container.is(':visible')) { 254 return; 255 } 256 var $filters = $container.closest('.cm-product-filters'); 257 var tooltipClass = $filters.data('caTooltipClass'); 258 var tooltipRightClass = $filters.data('caTooltipRightClass'); 259 var tooltipMobileClass = $filters.data('caTooltipMobileClass'); 260 var tooltipLayoutSelector = $filters.data('caTooltipLayoutSelector'); 261 var tooltipEventsTooltip = $filters.data('ceTooltipEventsTooltip'); 262 var containerFirstChild = $container.children(':first-child'); 263 var tooltipPosition = 'centerRight'; 264 var isRightOffsetCheckboxContainer = $(window).width() - ($container.offset().left + $container.outerWidth()) < $container.offset().left; 265 if (Tygh.language_direction !== 'rtl' && isRightOffsetCheckboxContainer || Tygh.language_direction === 'rtl' && !isRightOffsetCheckboxContainer) { 266 tooltipPosition = 'centerLeft'; 267 tooltipClass += ' ' + tooltipRightClass; 268 } 269 var $tooltip = $('<div/>', { 270 title: message, 271 'data-ce-tooltip': true, 272 'data-ce-tooltip-position': tooltipPosition, 273 'data-ca-tooltip-layout-selector': tooltipLayoutSelector, 274 'data-ce-tooltip-events-tooltip': tooltipEventsTooltip, 275 'class': tooltipClass, 276 html: '​', 277 height: containerFirstChild ? containerFirstChild.outerHeight() : '' 278 }); 279 $tooltip.prependTo($container).ceTooltip({ 280 onShow: function () { 281 var $trigger = this.getTrigger(); 282 var triggerRect = $trigger[0].getBoundingClientRect(); 283 var $tip = this.getTip(); 284 if (Tygh.language_direction === 'rtl') { 285 var checkboxContainer = $tooltip.closest('.ty-product-filters').length > 0 ? $tooltip.closest('.ty-product-filters') : $tooltip; 286 $tip.css({ 287 left: isRightOffsetCheckboxContainer ? checkboxContainer.offset().left - $tip.outerWidth(true) + 'px' : checkboxContainer.offset().left + checkboxContainer.outerWidth(true) + 'px' 288 }); 289 } 290 291 // Set tooltip position when scrolling. 292 var $filterBlock = $trigger.closest('.cm-filter-table'); 293 if ($filterBlock.length > 0) { 294 var topFilterBlockPosition = $filterBlock.position().top; 295 var bottomFilterBlockPosition = $filterBlock.position().top + $filterBlock.outerHeight(); 296 if ($tip.position().top > bottomFilterBlockPosition) { 297 $tip.css({ 298 top: bottomFilterBlockPosition - $tip.outerHeight() + 'px' 299 }); 300 } else if ($tip.position().top < topFilterBlockPosition) { 301 $tip.css({ 302 top: $filterBlock.position().top + 'px' 303 }); 304 } 305 } 306 } 307 }).ceTooltip('show').on('onHide', function () { 308 $tooltip.data('tooltip').getTip().remove(); 309 $tooltip.remove(); 310 }); 311 var isMobile = $('body').hasClass('screen--xs') || $('body').hasClass('screen--xs-large') || $('body').hasClass('screen--sm'); 312 if (isMobile) { 313 $('.tooltip').addClass(tooltipMobileClass); 314 } 315 setTimeout(function () { 316 $tooltip.ceTooltip('hide').remove(); 317 }, HIDE_DELAY); 318 } 319 function setCallback() { 320 // re-init filters 321 $.ceEvent('on', 'ce.commoninit', function (context) { 322 var $productFilters = $('.cm-product-filters', context); 323 if (context.is('.cm-product-filters')) { 324 $productFilters = $productFilters.add(context); 325 } 326 initSlider(context); 327 if (context && (context.is(document) || context.hasClass('cm-product-filters'))) { 328 $('.cm-filter-table').on('scroll', $.debounce(function (e) { 329 let $self = $(this), 330 variantListId = $self.attr('id'); 331 lastSelectedElms[variantListId] = $self.scrollTop(); 332 }, 100)); 333 moveScrollToLastPosition(); 334 } 335 if (!$productFilters.length) { 336 return; 337 } 338 $productFilters.each(function () { 339 var self = $(this);
340 if (self.data('caBaseUrl')) { 341 base_url = self.data('caBaseUrl'); 342 ajax_ids = self.data('caTargetId'); 343 } 344 setVisibilityResetFilters(self); 345 }); 346 restoreDropdownsState(context); 347 restoreFilteredTablesState(context); 348 restoreCursorState(); 349 restoreVariantsState($productFilters); 350 var $color_filter_selectors = context.find('[data-cm-product-color-filter="true"]:has(.cm-product-filters-checkbox:enabled)'); 351 if ($color_filter_selectors.length) { 352 $color_filter_selectors.on('click touch', function (e) { 353 var $color_filter_selector = $(this), 354 dependent_checkbox_id = $color_filter_selector.data('caProductColorFilterCheckboxId'), 355 $dependent_checkbox = $('#' + dependent_checkbox_id); 356 $color_filter_selector.toggleClass('selected'); 357 $dependent_checkbox.prop('checked', !$dependent_checkbox.prop('checked')); 358 $dependent_checkbox.trigger('change'); 359 }); 360 } 361 }); 362 $.ceEvent('on', 'ce.filterdate', function (elm, time_from, time_to) { 363 var cb = $('#elm_checkbox_' + elm.prop('id')); 364 cb.data('prevVal', cb.val()); 365 cb.val(time_from + '-' + time_to).prop('checked', true).trigger('change'); 366 }); 367 } 368 function initSlider(parent) { 369 parent.find('.cm-range-slider').each(function () { 370 var $el = $(this); 371 var id = $el.prop('id'); 372 var json_data = $('#' + id + '_json').val(); 373 if ($el.data('uiSlider') || !json_data) { 374 return false; 375 } 376 var data = $.parseJSON(json_data) || null; 377 if (!data) { 378 return false; 379 } 380 $el.slider({ 381 disabled: data.disabled, 382 range: true, 383 min: data.min, 384 max: data.max, 385 step: data.step, 386 values: [data.left, data.right], 387 slide: function (event, ui) { 388 abortRequest(); 389 $('#' + id + '_left').val(ui.values[0]); 390 $('#' + id + '_right').val(ui.values[1]); 391 }, 392 change: function (event, ui) { 393 abortRequest(); 394 var statusBoxDelay = REQUEST_DELAY; 395 var loadDelay = REQUEST_DELAY * 3; 396 397 // If the slider is dragged, remove the delay. 398 if (event.handleObj) { 399 loadDelay = statusBoxDelay = REQUEST_DELAY / 3; 400 } 401 timerStatusBox = setTimeout(function () { 402 $.toggleStatusBox('show', { 403 show_overlay: false 404 }); 405 }, statusBoxDelay); 406 var replacement = ui.values[0] + '-' + ui.values[1]; 407 if (data.extra) { 408 replacement = replacement + '-' + data.extra; 409 } 410 var $checkbox = $('#elm_checkbox_' + id); 411 timer = setTimeout(function () { 412 $checkbox.data('prevVal', $checkbox.val()); 413 $checkbox.val(replacement).prop('checked', true).trigger('change'); 414 }, loadDelay); 415 }, 416 start: function (event, ui) { 417 abortRequest(); 418 } 419 }); 420 if (data.left != data.min || data.right != data.max) { 421 var replacement = data.left + '-' + data.right; 422 if (data.extra) { 423 replacement = replacement + '-' + data.extra; 424 } 425 $('#elm_checkbox_' + id).val(replacement).prop('checked', true); 426 } 427 $('#' + id + '_left, #' + id + '_right').off('change input focus').on('change input focus', function () { 428 var $inputsContainer = $(this).closest('.cm-product-filters-checkbox-container'); 429 var $inputLeft = $inputsContainer.find('#' + id + '_left'); 430 var $inputRight = $inputsContainer.find('#' + id + '_right'); 431 var inputLeftValue = _.toNumeric($inputLeft.val()); 432 var inputRightValue = _.toNumeric($inputRight.val());
433 if (inputLeftValue === $inputLeft.data('caPreviousValue') && inputRightValue === $inputRight.data('caPreviousValue')) { 434 abortRequest(); 435 return; 436 } 437 $inputLeft.data('previousValue', inputLeftValue); 438 $inputRight.data('previousValue', inputRightValue); 439 $el.slider('values', [inputLeftValue, inputRightValue]); 440 }); 441 if ($el.parents('.filter-wrap').hasClass('open')) { 442 $el.parent('.price-slider').show(); 443 } 444 }); 445 } 446 setCallback(); 447 setHandler(); 448 })($); 449})(Tygh, Tygh.$);
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.