1// https://codepen.io/martinAnsty/pen/BCotE 2Math.easeIn = function (val, min, max, strength) { 3 val /= max; 4 5 return (max - 1) * Math.pow(val, strength) + min; 6}; 7 8(function($) { 9 function setSlider(_, target) { 10 var 11 that = this, 12 $element = $(target), 13 min = parseFloat($element.data().rangeMin), 14 max = parseFloat($element.data().rangeMax), 15 decimals = 0, 16 elementMin, 17 elementMax, 18 controlMin, 19 controlMax, 20 _options = { 21 behaviour: 'drag-tap', 22 connect: true, 23 range: { 24 'min': min, 25 'max': max 26 } 27 }; 28 29 // Logarithmic scale 30 if ($element.data().optionId == 'p' && (max - min) > 100) { 31 _options['pips'] = { 32 mode: 'range', 33 density: 4 34 }; 35 36 var _i = 25, _strength = 3.5; 37 38 if ((max - min) < 100) { 39 _strength = 2; 40 } 41 42 for (; _i < 100; _i += 25) { 43 _options['range'][_i + '%'] = Math.ceil(Math.easeIn(((max - min) / 100 * _i), min, max, _strength)); 44 } 45 } else { 46 _options['pips'] = { 47 mode: 'count', 48 values: 3, 49 density: 4 50 }; 51 } 52 53 if (max && min != max) { 54 _options['start'] = [ parseFloat($element.data().startMin), parseFloat($element.data().startMax) ]; 55 } else { 56 _options['start'] = parseFloat($element.data().startMin); 57 } 58 59 // Decimal 60 if (/\./.test($element.data().rangeMin) || /\./.test($element.data().rangeMax)) { 61 decimals = Math.max( 62 $element.data().rangeMin.toString().replace(/^\d+?\./, '').length, 63 $element.data().rangeMax.toString().replace(/^\d+?\./, '').length 64 ); 65 } 66 67 _options['format'] = { 68 to: function (value) { 69 return parseFloat(value).toFixed(decimals); 70 }, 71 from: function (value) { 72 return parseFloat(value).toFixed(decimals); 73 } 74 }; 75 76 noUiSlider.create($element.get(0), _options); 77 78 if ($element.data().elementMin && $($element.data().elementMin).length) { 79 elementMin = $($element.data().elementMin); 80 } 81 82 if ($element.data().elementMax && $($element.data().elementMax).length) { 83 elementMax = $($element.data().elementMax); 84 } 85 86 $element.get(0).noUiSlider.on('slide', function(values, handle, noformat) { 87 if (typeof values[0] != 'undefined') { 88 if (elementMin) { 89 elementMin.html(values[0]); 90 } 91 92 if ($element.data().controlMin && $($element.data().controlMin).length) { 93 $($element.data().controlMin).val(noformat[0].toFixed(decimals)); 94 } 95 } 96 97 if (typeof values[1] != 'undefined') { 98 if (elementMax) { 99 elementMax.html(values[1]); 100 } 101 102 if ($element.data().controlMax && $($element.data().controlMax).length) { 103 $($element.data().controlMax).val(noformat[1].toFixed(decimals)); 104 } 105 } 106 }); 107 108 $element.get(0).noUiSlider.on('change', function(_, __, values, tap, positions) { 109 that.params.remove.call(that, $element.data().optionId); 110 111 if ((positions[1] - positions[0]) < 100) { 112 that.params.set.call(that, $element.data().optionId, values[0].toFixed(decimals) + '-' + values[1].toFixed(decimals)); 113 } 114 115 that.update($element); 116 }); 117 118 if ($element.data().controlMin) { 119 that.$element.on('change', $element.data().controlMin, function(e) { 120 if (this.value == '') { 121 return false; 122 } 123 124 if (this.value < min || this.value > max) { 125 this.value = min; 126 } 127 128 $element.get(0).noUiSlider.set([this.value, null]); 129 }); 130 } 131 132 if ($element.data().controlMax) { 133 that.$element.on('change', $element.data().controlMax, function(e) { 134 if (this.value == '') { 135 return false; 136 } 137 138 if (this.value < min || this.value > max) { 139 this.value = max; 140 } 141 142 $element.get(0).noUiSlider.set([null, this.value]); 143 }); 144 } 145 }; 146 147 var ocfilter = { 148 timers: {}, 149 values: {}, 150 options: {}, 151 init: function(options) { 152 this.options = $.extend({}, options); 153 154 this.$element = $('#ocfilter'); 155 156 this.$fields = $('.option-values input', this.$element); 157 158 this.$target = $('.ocf-target', this.$element); 159 this.$values = $('label', this.$element); 160 161 var that = this; 162 163 this.$values.each(function() { 164 that.values[$(this).attr('id')] = this; 165 }); 166 167 this.$target.on('change', function(e) { 168 e.preventDefault(); 169 170 var 171 $element = $(this), 172 $buttonTarget = $element.closest('label'), 173 $dropdown = $element.closest('.dropdown'); 174 175 that.options.php.params = $element.val(); 176 177 if ($element.is(':radio')) { 178 $element.closest('.ocf-option-values').find('label.ocf-selected').removeClass('ocf-selected'); 179 } 180 181 $buttonTarget.toggleClass('ocf-selected', $element.prop('checked')); 182 183 that.update($buttonTarget); 184 }); 185 186 this.$element.on('click.ocf', '.dropdown-menu', function(e) { 187 $(this).closest('.dropdown').one('hide.bs.dropdown', function(e) { 188 return false; 189 }); 190 }); 191 192 this.$element.on('click.ocf', '.disabled, [disabled]', function(e) { 193 e.stopPropagation(); 194 e.preventDefault(); 195 }); 196 197 var hovered = false; 198 199 this.$element.on({ 200 'mouseenter': function(e) { 201 hovered = true; 202 }, 203 'mouseleave': function(e) { 204 hovered = false; 205 206 $('[aria-describedby="' + $(this).attr('id') + '"]').popover('toggle'); 207 } 208 }, '.popover').on('hide.bs.popover', '[aria-describedby^="popover"]', function(e) { 209 setTimeout(function(element) { 210 $(element).show(); 211 }, 0, e.target); 212 213 if (hovered) { 214 e.preventDefault(); 215 } 216 }); 217 218 this.$element.find('.dropdown').on('hide.bs.dropdown', function(e) { 219 that.$element.find('[aria-describedby^="popover"]').popover('hide'); 220 }); 221 222 if (this.options.php.manualPrice) { 223 $('[data-toggle=\'popover-price\']').popover({ 224 content: function() { 225 return '' + 226 '<div class="form-inline">' + 227 '<div class="form-group">' + 228 '<input name="price[min]" value="' + $('#price-from').text() + '" type="text" class="form-control input-sm" id="min-price-value" />' + 229 '</div>' + 230 '<div class="form-group">-</div>' + 231 '<div class="form-group">' + 232 '<input name="price[max]" value="' + $('#price-to').text() + '" type="text" class="form-control input-sm" id="max-price-value" />' + 233 '</div>' + 234 '</div>'; 235 }, 236 html: true, 237 delay: { 'show': 700, 'hide': 500 }, 238 placement: 'top', 239 container: '#ocfilter', 240 title: 'УказаÑÑ ÑенÑ', 241 trigger: 'hover' 242 }); 243 } 244 245 // Set sliders 246 $('#ocfilter .scale').each($.proxy(setSlider, this)); 247 }, 248 249 update: function(scrollTarget) { 250 var 251 that = this,
252 isSlider = scrollTarget.hasClass('scale'), 253 data = { 254 path: this.options.php.path, 255 option_id: scrollTarget.data().optionId 256 }; 257 258 if (this.options.php.params) { 259 data[this.options.php.index] = this.options.php.params; 260 } 261 262 this.preload(); 263 264 $.get('index.php?route=extension/module/ocfilter/callback', data, function(json) { 265 /* Start update */ 266 for (var i in json.values) { 267 var value = json.values[i], 268 target = $(that.values['v-' + i]), 269 total = value.t, 270 selected = value.s, 271 params = value.p; 272 273 if (target.length > 0) { 274 if (target.is('label')) { 275 if (total === 0 && !selected) { 276 target.addClass('disabled').removeClass('ocf-selected').find('input').attr('disabled', true).prop('checked', false); 277 } else { 278 target.removeClass('disabled').find('input').removeAttr('disabled'); 279 } 280 281 $('input', target).val(params); 282 283 if (that.options.php.showCounter) { 284 $('small', target).text(total); 285 } 286 } else { 287 target.prop('disabled', (total === 0)).val(params); 288 } 289 } 290 } 291 292 if (json.total === 0) { 293 $('#ocfilter-button button').removeAttr('onclick').addClass('disabled').text(that.options.text.select); 294 295 if (typeof scrollTarget != 'undefined' && scrollTarget.hasClass('scale')) { 296 $('#ocfilter .scale').removeAttr('disabled'); 297 } 298 } else { 299 if (that.options.php.searchButton || isSlider) { 300 $('#ocfilter-button button').attr('onclick', 'location = \'' + json.href + '\'').removeClass('disabled').text(json.text_total); 301 302 //$('#ocfilter .scale').removeAttr('disabled'); 303 } else { 304 window.location = json.href; 305 306 return; 307 } 308 } 309 310 that.$fields.filter('.enabled').removeAttr('disabled'); 311 312 if (typeof scrollTarget != 'undefined') { 313 that.scroll(scrollTarget); 314 } 315 316 if (isSlider) { 317 scrollTarget.removeAttr('disabled'); 318 } 319 320 if (!$.isPlainObject(json.sliders) || $.isEmptyObject(json.sliders)) { 321 return; 322 } 323 324 for (var option_id in json.sliders) { 325 var 326 $element = $('.scale[data-option-id="' + option_id + '"]').removeAttr('disabled'), 327 slider = $element.get(0).noUiSlider, 328 hasParam = that.params.has.call(that, option_id), 329 min = parseFloat(json.sliders[option_id]['min']), 330 max = parseFloat(json.sliders[option_id]['max']), 331 min_value = min, 332 max_value = max, 333 set = slider.get(); 334 335 if (!$.isArray(set)) { 336 set = [set, set]; 337 } 338 339 if (hasParam) { 340 if (set[1] <= max) { 341 max_value = set[1]; 342 } 343 344 if (set[0] >= min) { 345 min_value = set[0]; 346 } 347 } 348 349 if (min != max) { 350 slider.destroy(); 351 352 $element.data({ 353 startMin: min_value, 354 startMax: max_value, 355 rangeMin: min, 356 rangeMax: max 357 }); 358 359 if ($element.data().controlMin && $($element.data().controlMin).length) { 360 $($element.data().controlMin).val(min_value); 361 } 362 363 if ($element.data().controlMax && $($element.data().controlMax).length) { 364 $($element.data().controlMax).val(max_value); 365 } 366 367 if ($element.data().elementMin && $($element.data().elementMin).length) { 368 $($element.data().elementMin).html(min_value); 369 } 370 371 if ($element.data().elementMax && $($element.data().elementMax).length) { 372 $($element.data().elementMax).html(max_value); 373 } 374 375 setSlider.call(that, 0, $element.get(0)); 376 } else { 377 $element.attr('disabled', 'disabled'); 378 } 379 } 380 /* End update */ 381 }, 'json'); 382 }, 383 384 params: { 385 decode: function() { 386 var params = {}; 387 if (this.options.php.params) { 388 var matches = this.options.php.params.split(';'); 389 for (var i = 0; i < matches.length; i++) { 390 var parts = matches[i].split(':'); 391 params[parts[0]] = typeof parts[1] != 'undefined' ? parts[1].split(',') : []; 392 } 393 } 394 this.options.php.params = params; 395 }, 396 397 encode: function() { 398 var params = []; 399 if (this.options.php.params) { 400 for (i in this.options.php.params) { 401 params.push(i + ':' + (typeof this.options.php.params[i] == 'object' ? this.options.php.params[i].join(',') : this.options.php.params[i])); 402 } 403 } 404 this.options.php.params = params.join(';'); 405 }, 406 407 set: function(option_id, value_id) { 408 this.params.decode.call(this); 409 if (typeof this.options.php.params[option_id] != 'undefined') { 410 this.options.php.params[option_id].push(value_id); 411 } else { 412 this.options.php.params[option_id] = [value_id]; 413 } 414 this.params.encode.call(this); 415 }, 416 417 has: function(option_id) { 418 this.params.decode.call(this); 419 420 var has = (typeof this.options.php.params[option_id] != 'undefined'); 421 422 this.params.encode.call(this); 423 424 return has; 425 }, 426 427 remove: function(option_id, value_id) { 428 this.params.decode.call(this); 429 if (typeof this.options.php.params[option_id] != 'undefined') { 430 if (this.options.php.params[option_id].length === 1 || !value_id) { 431 delete this.options.php.params[option_id]; 432 } else { 433 this.options.php.params[option_id].splice(ocfilter.options.php.params[option_id].indexOf(value_id), 1); 434 } 435 } 436 this.params.encode.call(this); 437 } 438 }, 439 440 preload: function() { 441 if ($('.ocfilter-option-popover').length) { 442 $('.ocfilter-option-popover button').button('loading'); 443 } 444 445 this.$element.find('.scale').attr('disabled', 'disabled'); 446 setTimeout(function(that) { 447 that.$values.addClass('disabled').find('small').text('0'); 448 }, 10, this); 449 }, 450 451 scroll: function(target) { 452 var that = this; 453
454 if (target.find('input:checked').length < 1 && target.parent().find('input:checked').length > 0) { 455 target = target.parent().find('input:checked:first').parent(); 456 } 457 458 if (that.options.mobile && target.is('label')) { 459 target = target.find('input'); 460 } 461 462 if (target.is(':hidden')) { 463 target = target.parents(':visible:first'); 464 } 465 466 this.$element 467 .find('[aria-describedby^="popover"]') 468 .not('[data-toggle="popover-price"]') 469 .not(target) 470 .popover('destroy'); 471 472 if (!target.attr('aria-describedby')) { 473 var options = { 474 placement: that.options.mobile ? 'bottom' : 'right', 475 selector: that.options.mobile ? '> input' : false, 476 delay: { 'show': 400, 'hide': 600 }, 477 content: function() { 478 return $('#ocfilter-button').html(); 479 }, 480 container: that.$element, 481 trigger: 'hover', 482 html: true 483 }; 484 485 target.popover(options).popover('show'); 486 487 $('#' + target.attr('aria-describedby')).addClass('ocfilter-option-popover'); 488 } else { 489 $('#' + target.attr('aria-describedby') + ' button').replaceWith($('#ocfilter-button').html()); 490 } 491 } 492 }; 493 494 /* IE6+ */ 495 if (Object.create === undefined) { 496 Object.create = function(object) { 497 function f() {}; 498 f.prototype = object; 499 return new f(); 500 }; 501 } 502 503 $.fn.ocfilter = function(options) { 504 return this.each(function() { 505 var $element = $(this); 506 507 if ($element.data('ocfilter')) { 508 return $element.data('ocfilter'); 509 } 510 511 $element.data('ocfilter', Object.create(ocfilter).init(options, $element)); 512 }); 513 }; 514})(jQuery);
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.