Advertisement
Guest User

Untitled

a guest
Jun 7th, 2017
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * Mega Filter
  3.  */
  4.  
  5. if( typeof Array.prototype.indexOf == 'undefined' ) {
  6.     Array.prototype.indexOf = function(obj, start) {
  7.         for( var i = ( start || 0 ), j = this.length; i < j; i++ ) {
  8.             if( this[i] === obj ) {return i;}
  9.         }
  10.  
  11.         return -1;
  12.    };
  13. };
  14.  
  15. var MegaFilterINSTANCES = typeof MegaFilterINSTANCES == 'undefined' ? [] : MegaFilterINSTANCES;
  16.  
  17. var MegaFilter = function(){ };
  18.  
  19. MegaFilter.prototype = {
  20.  
  21.     /**
  22.      * Main box of filter
  23.      */
  24.     _box: null,
  25.  
  26.     /**
  27.      * Ooptions
  28.      */
  29.     _options: null,
  30.  
  31.     /**
  32.      * @var int
  33.      */
  34.     _timeoutAjax: null,
  35.  
  36.     _timeoutSearchFiled: null,
  37.  
  38.     /**
  39.     * @var string
  40.     */
  41.     _url            : null,
  42.  
  43.     /**
  44.      * URL separator
  45.      *
  46.      * @var string
  47.      */
  48.     _urlSep         : null,
  49.  
  50.     /**
  51.      * List of parameters
  52.      *
  53.      * @var object
  54.      */
  55.     _params         : null,
  56.  
  57.     /**
  58.      * List of scrolls
  59.      *
  60.      * @var array
  61.      */
  62.     _scrolls        : null,
  63.  
  64.     /**
  65.      * List of buttons
  66.      *
  67.      * @var array
  68.      */
  69.     _buttonsMore    : null,
  70.  
  71.     _liveFilters    : null,
  72.  
  73.     /**
  74.      * Main container
  75.      *
  76.      * @var jQuery
  77.      */
  78.     _jqContent      : null,
  79.  
  80.     /**
  81.      * Loader over results
  82.      *
  83.      * @var jQuery
  84.      */
  85.     _jqLoader       : null,
  86.  
  87.     /**
  88.      * Loader over filter
  89.      *
  90.      * @var jQuery
  91.      */
  92.     _jqLoaderFilter : null,
  93.  
  94.     /**
  95.      * Sliders
  96.      *
  97.      * @type array
  98.      */
  99.     _sliders        : null,
  100.  
  101.     /**
  102.      * ID of main container
  103.      *
  104.      * @var string
  105.      */
  106.     _contentId      : '#content',
  107.  
  108.     /**
  109.      * Waiting for server response
  110.      *
  111.      * @var bool
  112.      */
  113.     _busy           : false,
  114.  
  115.     /**
  116.      * Something was changed when loading data from the server
  117.      *
  118.      * @var bool
  119.      */
  120.     _waitingChanges : false,
  121.  
  122.     /**
  123.      * Last response
  124.      *
  125.      * @var string
  126.      */
  127.     _lastResponse   : '',
  128.  
  129.     _refreshPrice : function(){},
  130.  
  131.     _inUrl : null,
  132.  
  133.     _isInit: false,
  134.  
  135.     _cache: null,
  136.  
  137.     _relativeScroll: null,
  138.  
  139.     _selectOptions: null,
  140.  
  141.     _lastUrl: null,
  142.  
  143.     _urlToFilters: null,
  144.  
  145.     _instanceIdx: 0,
  146.  
  147.     _inlineHorizontalUpdate: null,
  148.  
  149.     _lastEvent: null,
  150.  
  151.     _startUrl: null,
  152.  
  153.     _history: 1,
  154.  
  155.     _changed: false,
  156.  
  157.     _ajaxPagination: null,
  158.  
  159.     _seoAliases: null,
  160.  
  161.     _selectedFilters: null,
  162.  
  163.     ////////////////////////////////////////////////////////////////////////////
  164.  
  165.     /**
  166.      * Init class
  167.      */
  168.     init: function( box, options ) {
  169.         var self = this,
  170.             i;
  171.  
  172.         self._instanceIdx = MegaFilterINSTANCES.length;
  173.  
  174.         if( options.routeHome == options.route && options.homePageAJAX ) {
  175.             self._contentId = options.homePageContentSelector;
  176.         } else if( options.contentSelector ) {
  177.             self._contentId = options.contentSelector;
  178.         }
  179.  
  180.         self._jqContent = jQuery(self._contentId);
  181.         self._options   = options;
  182.  
  183.         if( ! self._jqContent.length ) {
  184.             self._contentId = '#maincontent';
  185.  
  186.             self._jqContent = jQuery(self._contentId);
  187.         }
  188.  
  189.         if( options.routeHome == options.route && options.homePageAJAX && box.hasClass( 'mfilter-content_top' ) && box.parents(self._contentId) ) {
  190.             self._jqContent.parent().prepend( box.addClass('col-sm-12') );
  191.         }
  192.  
  193.         if( self._startUrl === null ) {
  194.             self._startUrl = self.location();
  195.         }
  196.  
  197.         self._seoAliases                = {};
  198.         self._scrolls                   = [];
  199.         self._buttonsMore               = [];
  200.         self._liveFilters               = [];
  201.         self._sliders                   = [];
  202.         self._inlineHorizontalUpdate    = [];
  203.         self._box                       = box;
  204.         self._selectOptions             = {};
  205.         self._cache                     = {
  206.             'lastResponse'  : {},
  207.             'mainContent'   : {}
  208.         };
  209.  
  210.         if( self._box.tooltip ) {
  211.             self._box.find('[data-mf-toggle="tooltip"]').tooltip({
  212.                 'viewport' : 'body',
  213.                 'container' : 'body'
  214.             });
  215.         }
  216.  
  217.         self.initResponsive();
  218.  
  219.         if( self._options.manualInit && ! self._isInit ) {
  220.             var items = self._box.find('> .mfilter-content').find('> ul,> div').hide(),
  221.                 $init = jQuery('<a href="#" style="padding: 10px; text-align: center; display: block;">' + self._options.text.init_filter + '</a>').appendTo( self._box.find('> .mfilter-content') );
  222.  
  223.             $init.click(function(){
  224.                 $init.text( self._options.text.initializing );
  225.  
  226.                 setTimeout(function(){
  227.                     items.show();
  228.                     self.boot();
  229.                     $init.remove();
  230.                 },100);
  231.  
  232.                 return false;
  233.             });
  234.         } else {
  235.             self.boot();
  236.         }
  237.  
  238.         return self;
  239.     },
  240.  
  241.     boot: function() {
  242.         var self = this,
  243.             i;
  244.  
  245.         self.initUrls();
  246.  
  247.         for( i in self._options.params ) {
  248.             if( typeof self._options.params[i] == 'function' ) continue;
  249.  
  250.             if( typeof self._params[i] == 'undefined' ) {
  251.                 self._params[i] = self._options.params[i];
  252.             }
  253.         }
  254.  
  255.         self.initSliders();
  256.  
  257.         //var t = this.microtime(true);
  258.         for( i in self ) {
  259.             if( i.indexOf( '_init' ) === 0 ) {
  260.                 self[i]();
  261.             }
  262.         }
  263.         //alert(this.microtime(true)-t);
  264.         self._isInit = true;
  265.  
  266.         if( self._options.route == self._options.routeHome && self._params.mfp ) {
  267.             setTimeout(function(){
  268.                 self.ajax();
  269.             },50);
  270.         }
  271.  
  272.         if( self._params.mfp ) {
  273.             self.setFiltersByUrl();
  274.         }
  275.     },
  276.  
  277.     microtime: function(get_as_float) {
  278.         var now = new Date()
  279.             .getTime() / 1000;
  280.         var s = parseInt(now, 10);
  281.  
  282.         return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s;
  283.     },
  284.  
  285.     keys: function( obj ) {
  286.         var keys = [];
  287.  
  288.         for( var i in obj ) {
  289.             keys.push( i );
  290.         }
  291.  
  292.         return keys;
  293.     },
  294.  
  295.     base64_decode: function(data) {
  296.         var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  297.         var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
  298.           ac = 0,
  299.           dec = '',
  300.           tmp_arr = [];
  301.  
  302.         if (!data) {
  303.           return data;
  304.         }
  305.  
  306.         data += '';
  307.  
  308.         do { // unpack four hexets into three octets using index points in b64
  309.           h1 = b64.indexOf(data.charAt(i++));
  310.           h2 = b64.indexOf(data.charAt(i++));
  311.           h3 = b64.indexOf(data.charAt(i++));
  312.           h4 = b64.indexOf(data.charAt(i++));
  313.  
  314.           bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
  315.  
  316.           o1 = bits >> 16 & 0xff;
  317.           o2 = bits >> 8 & 0xff;
  318.           o3 = bits & 0xff;
  319.  
  320.           if (h3 == 64) {
  321.             tmp_arr[ac++] = String.fromCharCode(o1);
  322.           } else if (h4 == 64) {
  323.             tmp_arr[ac++] = String.fromCharCode(o1, o2);
  324.           } else {
  325.             tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
  326.           }
  327.         } while (i < data.length);
  328.  
  329.         dec = tmp_arr.join('');
  330.  
  331.         return dec.replace(/\0+$/, '');
  332.     },
  333.  
  334.     sortKeys: function( data ) {
  335.         var keys = [],
  336.             sortData = [],
  337.             i;
  338.  
  339.         for( i in data ) {
  340.             sortData.push( [ i, data[i] ] );
  341.         }
  342.  
  343.         sortData.sort(function(a,b){
  344.             var sa = typeof a[1].sort_order == 'undefined' ? 0 : a[1].sort_order,
  345.                 sb = typeof b[1].sort_order == 'undefined' ? 0 : b[1].sort_order;
  346.  
  347.             if( sa > sb ) {
  348.                 return 1;
  349.             } else if( sa < sb ) {
  350.                 return -1;
  351.             }
  352.  
  353.             return 0;
  354.         });
  355.  
  356.         for( i = 0; i < sortData.length; i++ ) {
  357.             keys.push( sortData[i][0] );
  358.         }
  359.  
  360.         return keys;
  361.     },
  362.  
  363.     urldecode: function(str) {
  364.       return decodeURIComponent((str + '')
  365.         .replace(/%(?![\da-f]{2})/gi, function () {
  366.           return '%25'
  367.         })
  368.         .replace(/\+/g, '%20'))
  369.     },
  370.  
  371.     /**
  372.      * Init sliders
  373.      *
  374.      * @return void
  375.      */
  376.     initSliders: function(){
  377.         var self = this,
  378.             _init = false;
  379.  
  380.         function d( txt ) {
  381.             var $i = jQuery('<div>').html( txt ),
  382.                 txt2 = $i.text();
  383.             $i.remove();
  384.             return txt2;
  385.         }
  386.  
  387.         self._box.find('li.mfilter-filter-item.mfilter-slider').each(function(i){
  388.             var _this       = jQuery(this).attr('data-slider-id', i),
  389.                 seo_name    = _this.attr('data-seo-name'),
  390.                 data        = jQuery.parseJSON(self.base64_decode(_this.find('.mfilter-slider-data').html())),
  391.                 $min        = _this.find('.mfilter-opts-slider-min'),
  392.                 $max        = _this.find('.mfilter-opts-slider-max'),
  393.                 $slider     = _this.find('.mfilter-slider-slider'),
  394.                 update      = false,
  395.                 keys, values, map;
  396.  
  397.             function init( data, update ) {
  398.                 if( update ) {
  399.                     return;
  400.                 }
  401.  
  402.                 keys    = self.sortKeys( data );
  403.  
  404.                 if( _init ) {
  405.                     if( ! keys.length ) {
  406.                         $slider.slider().slider('disable');
  407.  
  408.                         return;
  409.                     } else {
  410.                         $slider.slider().slider('enable');
  411.                     }
  412.                 }
  413.  
  414.                 if( keys.length == 1 ) {
  415.                     data['copy'] = data[keys[0]];
  416.                     keys.push('copy');
  417.                 }
  418.  
  419.                 var filters = /*update ? self.filters() :*/ self.urlToFilters();
  420.  
  421.                 values  = typeof filters[seo_name] != 'undefined' ? (function(){
  422.                     var d = [];
  423.  
  424.                     for( var i = 0; i < filters[seo_name].length; i++ ) {
  425.                         d[i] = self.decode( self.urldecode( filters[seo_name][i] ) );
  426.                     }
  427.  
  428.                     return d;
  429.                 })() : [ data[keys[0]].key, data[keys[keys.length-1]].key ];
  430.                 map     = (function(){
  431.                     var m = [ keys.indexOf( values[0] ), keys.indexOf( values[values.length-1] ) ];
  432.  
  433.                     if( m[0] != -1 && m[1] != -1 ) {
  434.                         return typeof filters[seo_name] == 'undefined' ? [ 0, keys.length-1 ] : m;
  435.                     }
  436.  
  437.                     for( var i = 0; i < keys.length; i++ ) {
  438.                         if( m[0] == -1 ) {
  439.                             if( values[0] == d( data[keys[i]].value ) ) {
  440.                                 m[0] = i;
  441.                             }
  442.                         } else if( m[1] == -1 ) {
  443.                             if( values[values.length-1] == d( data[keys[i]].value ) ) {
  444.                                 m[1] = typeof data['copy'] == 'undefined' ? i : ( typeof filters[seo_name] == 'undefined' ? 1 : m[0] );
  445.                             }
  446.                         } else {
  447.                             break;
  448.                         }
  449.                     }
  450.  
  451.                     if( m[0] == -1 ) {
  452.                         m[0] = 0;
  453.                     }
  454.  
  455.                     if( m[1] == -1 ) {
  456.                         m[1] = m[0];//keys.length-1;
  457.                     }
  458.  
  459.                     return m;
  460.                 })();
  461.  
  462.                 $min.attr('data-key',map[0]).attr('data-min',0).val( d( data[keys[map[0]]].name ) );
  463.                 $max.attr('data-key',map[1]).attr('data-max',keys.length-1).val( d( data[keys[map[1]]].name ) );
  464.  
  465.                 $slider.slider({
  466.                     range   : true,
  467.                     min     : 0,
  468.                     max     : keys.length-1,
  469.                     values  : map,
  470.                     isRTL   : self._options.direction == 'rtl',
  471.                     slide   : function( e, ui ) {
  472.                         if( typeof keys[ui.values[0]] == 'undefined' || typeof data[keys[ui.values[0]]] == 'undefined' )
  473.                             return;
  474.  
  475.                         if( typeof keys[ui.values[1]] == 'undefined' || typeof data[keys[ui.values[1]]] == 'undefined' )
  476.                             return;
  477.  
  478.                         $min.attr('data-key',ui.values[0]).val( d( data[keys[ui.values[0]]].name ) );
  479.                         $max.attr('data-key',ui.values[1]).val( d( data[keys[ui.values[1]]].name ) );
  480.                     },
  481.                     stop    : function( e, ui ) {
  482.                         update = true;
  483.  
  484.                         if( self._options['refreshResults'] != 'using_button' ) {
  485.                             self.runAjax();
  486.                         }
  487.                     }
  488.                 });
  489.  
  490.                 if( _init ) {
  491.                     $slider.slider( 'value', $slider.slider('value') );
  492.                 }
  493.  
  494.                 _init = true;
  495.             }
  496.  
  497.             init( data );
  498.  
  499.             var s_idx = self._sliders.length;
  500.  
  501.             self._sliders.push({
  502.                 data: data,
  503.                 init: function( data, update ) {
  504.                     init( data, update );
  505.                 },
  506.                 resetValues: function(){
  507.                     data = self._sliders[s_idx].data;
  508.                     keys = self.sortKeys( data );
  509.  
  510.                     $min.attr('data-key',0).attr('data-min',0).val( d( data[keys[map[0]]].name ) );
  511.                     $max.attr('data-key',keys.length-1).attr('data-max',keys.length-1).val( d( data[typeof keys[map[1]] != 'undefined' ? keys[map[1]] : keys[map[0]]].name ) );
  512.  
  513.                     $slider.slider( 'option', 'min', parseInt( $min.attr('data-min') ) );
  514.                     $slider.slider( 'option', 'max', parseInt( $max.attr('data-max') ) );
  515.                     $slider.slider( 'option', 'values', [
  516.                         $min.attr('data-min'),
  517.                         $max.attr('data-max')
  518.                     ]);
  519.                     $slider.slider( 'value', $slider.slider( 'value' ) );
  520.  
  521.                     update = true;
  522.                 },
  523.                 setValues: function(){
  524.                     var vals = $slider.slider('values');
  525.  
  526.                     $min.attr('data-key',vals[0]).val( d( data[keys[vals[0]]].name ) );
  527.                     $max.attr('data-key',vals[1]).val( d( data[typeof keys[map[1]] != 'undefined' ? keys[map[1]] : keys[map[0]]].name ) );
  528.                 },
  529.                 getValues: function(){
  530.                     if( $min.attr('data-key') == $min.attr('data-min') && $max.attr('data-key') == $max.attr('data-max') && self.keys( data ).length == self.keys( self._sliders[s_idx].data ).length ) {
  531.                         return [];
  532.                     }
  533.  
  534.                     var min     = parseInt( $min.attr('data-key') ),
  535.                         max     = parseInt( $max.attr('data-key') ),
  536.                         vals    = [];
  537.  
  538.                     for( var i = min; i <= max; i++ ) {
  539.                         var key = keys[i];
  540.  
  541.                         if( ! key ) continue;
  542.  
  543.                         if( typeof data[key] == 'undefined' ) {
  544.                             key = keys[0];
  545.                         }
  546.  
  547.                         vals.push( encodeURIComponent( self.encode( d( data[key].value ) ) ) );
  548.                     }
  549.  
  550.                     return vals;
  551.                 }
  552.             });
  553.         });
  554.     },
  555.  
  556.     initResponsive: function(){
  557.         var self    = this,
  558.             column  = null,
  559.             moved   = false,
  560.             hidden  = true;
  561.  
  562.         if( self._box.hasClass( 'mfilter-hide-container' ) ) {
  563.             column = self._box.parent();
  564.             self._box.removeClass( 'mfilter-content_top mfilter-modern-horizontal mfilter-hide' );
  565.         } else if( self._box.hasClass( 'mfilter-column_left' ) ) {
  566.             column = jQuery('#column-left');
  567.         } else if( self._box.hasClass( 'mfilter-column_right' ) ) {
  568.             column = jQuery('#column-right');
  569.         } else {
  570.             return;
  571.         }
  572.  
  573.         var id = 'mfilter-free-container-' + jQuery('[id^="mfilter-free-container"]').length,
  574.             locked = false,
  575.             control = false,
  576.             src = jQuery('<span class="mfilter-before-box">'),
  577.             cnt, cnt2, cnt3, btn;
  578.  
  579.         if( ! jQuery( '.mfilter-free-container' ).length ) {
  580.             control = true;
  581.  
  582.             cnt = jQuery('<div class="mfilter-free-container mfilter-free-container-closed mfilter-direction-' + self._options.direction + ( self._options.isMobile ? ' mfilter-mobile' : '' ) + '">')
  583.                 .prependTo( jQuery('body') );
  584.  
  585.             btn = jQuery('<div class="mfilter-free-button">')
  586.                 .appendTo( cnt )
  587.                 .click(function(){
  588.                     if( locked ) return false;
  589.  
  590.                     locked = true;
  591.  
  592.                     if( hidden ) {
  593.                         cnt.animate(self._options.direction == 'rtl' ? {
  594.                             'marginRight' : 0
  595.                         } : {
  596.                             'marginLeft' : 0
  597.                         }, 500, function(){
  598.                             locked = false;
  599.  
  600.                             self._relativeScroll.refresh();
  601.                             // On 2017-05-17 kanenas said: Remove knns-mfilter class
  602.                             cnt.addClass('mfilter-free-container-opened').removeClass('mfilter-free-container-closed knns-mfilter');
  603.  
  604.                             for( var i in self._scrolls ) {
  605.                                 self._scrolls[i].refresh();
  606.                             }
  607.                         });
  608.                     } else {
  609.                         cnt.animate(self._options.direction == 'rtl' ? {
  610.                             'marginRight' : - ( cnt.outerWidth(true)<cnt.outerWidth()?cnt.outerWidth():cnt.outerWidth(true) )
  611.                         } : {
  612.                             'marginLeft' : - cnt.outerWidth(true)
  613.                         }, 500, function(){
  614.                             locked = false;
  615.                             cnt.addClass('mfilter-free-container-closed').removeClass('mfilter-free-container-opened');
  616.  
  617.                             jQuery('body > div.tooltip.fade.top.in').remove();
  618.                         });
  619.                     }
  620.  
  621.                     hidden = ! hidden;
  622.                 });
  623.  
  624.             cnt2 = jQuery('<div class="mfilter-iscroll">')
  625.                 .css('overflow','hidden')
  626.                 .attr('id', id)
  627.                 .appendTo( cnt );
  628.  
  629.             cnt3 = jQuery('<div>')
  630.                 .appendTo( cnt2 );
  631.         } else {
  632.             cnt = jQuery( '.mfilter-free-container' );
  633.             cnt2 = cnt.find( '.mfilter-iscroll:first' );
  634.             cnt3 = cnt2.find( '> div:first' );
  635.             btn = jQuery( '.mfilter-free-button ');
  636.         }
  637.  
  638.         function reinit() {
  639.             var init = false,
  640.                 $self = jQuery('#'+id);
  641.  
  642.             return {
  643.                 refresh : function(){
  644.                     if( init ) {
  645.                         return;
  646.                     }
  647.  
  648.                     init = true;
  649.  
  650.                     $self.scrollbar();
  651.                 },
  652.                 reinit: function(){
  653.  
  654.                 }
  655.             };
  656.         }
  657.  
  658.         if( control ) {
  659.             self._relativeScroll = reinit();
  660.         }
  661.  
  662.         self._box.before( src );
  663.  
  664.         if( ! column.length ) {
  665.             column = self._box.parent();
  666.         }
  667.  
  668.         function isVisible() {
  669.             var displayAlwaysAsWidget = false;
  670.  
  671.             self.eachInstances(function( self ){
  672.                 if( ! displayAlwaysAsWidget ) {
  673.                     displayAlwaysAsWidget = self._options.displayAlwaysAsWidget;
  674.                 }
  675.             });
  676.  
  677.             var visible = self._options.displayAlwaysAsWidget ? false : column.is(':visible'),
  678.                 height  = jQuery(window).height() - 50;
  679.  
  680.             if( displayAlwaysAsWidget ) {
  681.                 cnt.show();
  682.             }
  683.  
  684.             if( visible && moved ) {
  685.                 if( control ) {
  686.                     cnt.hide();
  687.                 }
  688.  
  689.                 src.after( self._box );
  690.  
  691.                 if( control ) {
  692.                     if( ! hidden ) {
  693.                         btn.trigger('click');
  694.                     }
  695.                 }
  696.  
  697.                 moved = false;
  698.             } else if( ! visible && ! moved ) {
  699.                 if( control ) {
  700.                     cnt.show();
  701.                 }
  702.  
  703.                 cnt3.append( self._box );
  704.  
  705.                 moved = true;
  706.             }
  707.  
  708.             if( displayAlwaysAsWidget || control ) {
  709.                 if( moved ) {
  710.                     self.eachInstances(function( self ){
  711.                         if( self._relativeScroll ) {
  712.                             cnt2.attr('data-max-height', height).css( 'max-height', height + 'px' );
  713.                             self._relativeScroll.refresh();
  714.                         }
  715.                     });
  716.                 }
  717.             }
  718.         }
  719.  
  720.         jQuery(window).resize(function() {
  721.             isVisible();
  722.         });
  723.  
  724.         setTimeout(function(){
  725.             isVisible();
  726.         },100);
  727.  
  728.         if( control ) {
  729.             if( self._options.isMobile && self._options.widgetWithSwipe ) {
  730.                 jQuery(document).hammer({
  731.                     direction: Hammer.DIRECTION_HORIZONTAL
  732.                 }).bind('panright panleft', function(e){
  733.                     if( ( self._options.direction == 'rtl' && e.type == 'panleft' ) || ( self._options.direction != 'rtl' && e.type == 'panright' ) ) {
  734.                         if( hidden ) {
  735.                             btn.trigger('click');
  736.                         }
  737.                     } else if( ( self._options.direction == 'rtl' && e.type == 'panright' ) || ( self._options.direction != 'rtl' && e.type == 'panleft' ) ) {
  738.                         if( ! hidden ) {
  739.                             btn.trigger('click');
  740.                         }
  741.                     }
  742.                 });
  743.             }
  744.         }
  745.     },
  746.  
  747.     location: function(){
  748.         var self = this,
  749.             url = document.location.href.toString();
  750.  
  751.         if( self._options.seo.alias != '' ) {
  752.             url = url.replace( '/' + encodeURIComponent( self._options.seo.alias ), '' );
  753.         }
  754.  
  755.         for( var i in self._seoAliases ) {
  756.             url = url.replace( '/' + encodeURIComponent( self._seoAliases[i] ), '' );
  757.         }
  758.  
  759.         return url;
  760.     },
  761.  
  762.     removeMfpFromUrl: function( url ) {
  763.         if( url.match( /\/mfp,([a-z0-9\-_]+\[[^\]]*\],?)+/g ) ) {
  764.             return url.replace( /\/mfp,([a-z0-9\-_]+\[[^\]]*\],?)+/g, '' );
  765.         }
  766.  
  767.         return url.replace( /\/mfp\/([a-z0-9\-_]+,[^\/\?]+\/?)+/, '' );
  768.     },
  769.  
  770.     locationPath: function(){
  771.         var self = this,
  772.             location = self.location();
  773.  
  774.         return self.removeMfpFromUrl( decodeURIComponent( self.parse_url( location ).path ) );
  775.     },
  776.  
  777.     initUrls: function( url ) {
  778.         var self = this;
  779.  
  780.         if( typeof url == 'undefined' ) {
  781.             url  = self.location().split('#')[0];
  782.         }
  783.  
  784.         self._urlSep    = self._parseSep( url ).urlSep;
  785.         self._url       = self._parseSep( url ).url;
  786.         self._params    = self._parseUrl( url );
  787.         self._inUrl     = self._parseUrl( url );
  788.     },
  789.  
  790.     _initMfImage: function() {
  791.         var self = this;
  792.  
  793.         self._box.find('.mfilter-image input').change(function(){
  794.             var s = jQuery(this).is(':checked'),
  795.                 t = jQuery(this).attr('type');
  796.  
  797.             if( t == 'radio' ) {
  798.                 jQuery(this).parent().parent().find('.mfilter-image-checked').removeClass('mfilter-image-checked');
  799.             }
  800.  
  801.             jQuery(this).parent()[s?'addClass':'removeClass']('mfilter-image-checked');
  802.         });
  803.  
  804.         self._box.find('.mfilter-image input:checked').parent().addClass('mfilter-image-checked');
  805.     },
  806.  
  807.     __initTreeCategoryEvents: function() {
  808.         var self = this,
  809.             $path = self._box.find('input[name="path"]');
  810.  
  811.         self._box.find('li.mfilter-filter-item.mfilter-tree.mfilter-categories')[self._box.find('.mfilter-category-tree > ul > li').length?'show':'hide']();
  812.  
  813.         self._box.find('.mfilter-category-tree').each(function(){
  814.             var _this = jQuery(this),
  815.                 ul = _this.find('> ul'),
  816.                 top_url = ul.attr('data-top-url'),
  817.                 top_path = (typeof self._options.params['path'] == 'undefined'?'':self._options.params['path']).split('_');
  818.  
  819.             _this.find('.mfilter-to-parent a').unbind('click').bind('click', function(){
  820.                 var parts = (jQuery(this).attr('data-path')?jQuery(this).attr('data-path'):$path.val()).split('_'),
  821.                     count = parts.length - 1;
  822.  
  823.                 parts.pop();
  824.  
  825.                 if( self._path() == parts.join('_') && self._options.params.path ) {
  826.                     parts = [];
  827.                 }
  828.  
  829.                 if( top_url != '' && count < top_path.length ) {
  830.                     window.location.href = self.createUrl(top_url);
  831.                 } else {
  832.                     $path.val( parts.length || ! self._options.params.path ? parts.join('_') : self._path() );
  833.  
  834.                     self.runAjax();
  835.                 }
  836.  
  837.                 return false;
  838.             });
  839.  
  840.             _this.find('a[data-parent-id]').click(function(){
  841.                 if( self._busy ) return false;
  842.  
  843.                 var id = jQuery(this).attr('data-id'),
  844.                     path = $path.val(),
  845.                     parts = path.split('_'),
  846.                     last = parts[parts.length-1].split(',');
  847.  
  848.                 self._cache['cat_'+id] = jQuery(this).text();
  849.  
  850.                 if( last.indexOf( id ) == -1 ) {
  851.                     if( path != '' ) {
  852.                         path += '_';
  853.                     }
  854.  
  855.                     path += id;
  856.  
  857.                     $path.val( path );
  858.                 }
  859.  
  860.                 self.runAjax();
  861.  
  862.                 return false;
  863.             });
  864.         });
  865.     },
  866.  
  867.     _path: function( skip_org ){
  868.         var self = this;
  869.  
  870.         if( skip_org !== true && typeof self._options.params.mfp_org_path_aliases != 'undefined' && self._options.params.mfp_org_path_aliases != '' ) {
  871.             return self._options.params.mfp_org_path_aliases;
  872.         } else if( skip_org !== true && typeof self._options.params.mfp_org_path != 'undefined' && self._options.params.mfp_org_path != '' ) {
  873.             return self._options.params.mfp_org_path;
  874.         } else if( typeof self._options.params.mfp_path_aliases != 'undefined' ) {
  875.             return self._options.params.mfp_path_aliases;
  876.         } else if( typeof self._options.params.mfp_path != 'undefined' ) {
  877.             return self._options.params.mfp_path;
  878.         } else if( typeof self._options.params.path_aliases != 'undefined' ) {
  879.             return self._options.params.path_aliases;
  880.         } else if( typeof self._options.params.path != 'undefined' ) {
  881.             return self._options.params.path;
  882.         }
  883.  
  884.         return '';
  885.     },
  886.  
  887.     _initTreeCategory: function( force ) {
  888.         var self = this,
  889.             $path = self._box.find('input[name="path"]');
  890.  
  891.         if( self._isInit && force !== true ) {
  892.             self.__initTreeCategoryEvents();
  893.  
  894.             return;
  895.         }
  896.  
  897.         if( ! $path.val() && ! self._isInit ) {
  898.             $path.val( self._path( true ) );
  899.         }
  900.  
  901.         self._box.find('.mfilter-category-tree').each(function(){
  902.             var filters = self.filters();
  903.  
  904.             if( ( typeof filters.path != 'undefined' && filters.path != self._path() ) || $path.val().indexOf( '_' ) > -1 || ( $path.val() && ! self._options.params.path ) || ( $path.val() && self._options.route != self._options.routeCategory ) ) {
  905.                 jQuery(this).find('ul').prepend(jQuery('<li class="mfilter-to-parent">')
  906.                     .append(jQuery('<a>')
  907.                         .html((function(){
  908.                             var parts = $path.val().split('_'),
  909.                                 cat = parts[parts.length-1];
  910.  
  911.                             return typeof self._cache['cat_'+cat] != 'undefined' ? self._cache['cat_'+cat] : self._options.text.go_to_top;
  912.                         }))
  913.                     )
  914.                 );
  915.             }
  916.         });
  917.  
  918.         self.__initTreeCategoryEvents();
  919.     },
  920.  
  921.     _initBox: function() {
  922.         var self = this;
  923.  
  924.         if( self._isInit ) return;
  925.  
  926.         if( self._box.hasClass( 'mfilter-content_top' ) ) {
  927.             self._box.find('.mfilter-content > ul > li').each(function(i){
  928.                 if( i && i % 4 == 0 ) {
  929.                     jQuery(this).before('<li style="clear:both; display:block;"></li>');
  930.                 }
  931.             });
  932.         }
  933.     },
  934.  
  935.     _initTextFields: function() {
  936.         var self = this;
  937.  
  938.         self._box.find('.mfilter-filter-item.mfilter-text').each(function(){
  939.             var _this   = jQuery(this),
  940.                 name    = _this.attr('data-seo-name'),
  941.                 input   = _this.find('input[type=text]');
  942.  
  943.             function clear() {
  944.                 if( self._cache['txt_field_'+name] ) {
  945.                     clearTimeout( self._cache['txt_field_'+name] );
  946.                 }
  947.  
  948.                 self._cache['txt_field_'+name] = null;
  949.             }
  950.  
  951.             input.bind('keydown', function(e){
  952.                 if( e.keyCode == 13 ) {
  953.                     clear();
  954.  
  955.                     self.ajax();
  956.  
  957.                     return false;
  958.                 }
  959.             }).bind('keyup.mf_shv', function(){
  960.                 input[input.val()?'addClass':'removeClass']('mfilter-text-has-value');
  961.             }).bind('keyup', function(e){
  962.                 clear();
  963.  
  964.                 if( self._options['refreshResults'] != 'using_button' ) {
  965.                     self._cache['txt_field_'+name] = setTimeout(function(){
  966.                         self.ajax();
  967.  
  968.                         self._cache['txt_field_'+name] = null;
  969.                     }, 1000);
  970.                 }
  971.             }).trigger('keyup.mf_shv');
  972.         });
  973.     },
  974.  
  975.     _initSearchFiled: function() {
  976.         var self = this,
  977.             searchField = self._box.find('input[id="mfilter-opts-search"]'),
  978.             searchButton = self._box.find('[id="mfilter-opts-search_button"]');
  979.  
  980.         if( ! searchField.length )
  981.             return;
  982.  
  983.         var refreshDelay = parseInt( searchField.unbind('keyup keydown click paste propertychange').attr('data-refresh-delay').toString().replace(/[^0-9\-]+/, '') ),
  984.             lastValue = searchField.val(),
  985.             eventTimeout = null;
  986.  
  987.         function clearInt() {
  988.             if( self._timeoutSearchFiled )
  989.                 clearTimeout( self._timeoutSearchFiled );
  990.  
  991.             self._timeoutSearchFiled = null;
  992.         }
  993.  
  994.         if( refreshDelay != '-1' ) {
  995.             searchField.bind('keyup paste propertychange', function(e){
  996.                 var $self = jQuery(this);
  997.  
  998.                 clearTimeout( eventTimeout );
  999.  
  1000.                 eventTimeout = setTimeout(function(){
  1001.                     if( $self.val() == lastValue )
  1002.                         return;
  1003.  
  1004.                     if( ! refreshDelay ) {
  1005.                         self.ajax();
  1006.                     } else if( e.keyCode != 13 ) {
  1007.                         clearInt();
  1008.  
  1009.                         self._timeoutSearchFiled = setTimeout(function(){
  1010.                             self.ajax();
  1011.  
  1012.                             self._timeoutSearchFiled = null;
  1013.                         }, refreshDelay);
  1014.                     }
  1015.  
  1016.                     lastValue = searchField.val();
  1017.                     eventTimeout = null;
  1018.                 },10);
  1019.             });
  1020.         }
  1021.  
  1022.         searchField.bind('keydown', function(e){
  1023.             if( e.keyCode == 13 ) {
  1024.                 $(this).trigger('change');
  1025.  
  1026.                 return false;
  1027.             }
  1028.         }).bind('change',function(){
  1029.             if( jQuery(this).val() != lastValue ) {
  1030.                 clearInt();
  1031.  
  1032.                 self.ajax();
  1033.             }
  1034.         }).bind('resetvalue',function(){
  1035.             lastValue = jQuery(this).val();
  1036.         }).bind('keyup.mf_shv', function(){
  1037.             jQuery(this)[jQuery(this).val()?'addClass':'removeClass']('mfilter-search-has-value');
  1038.         }).trigger('keyup.mf_shv');
  1039.  
  1040.         searchButton.bind('click', function(){
  1041.             clearInt();
  1042.  
  1043.             self.ajax();
  1044.  
  1045.             return false;
  1046.         });
  1047.     },
  1048.  
  1049.     encode: function( string ) {
  1050.         string = string.replace( /,/g, 'LA==' );
  1051.         string = string.replace( /\[/g, 'Ww==' );
  1052.         string = string.replace( /\]/g, 'XQ==' );
  1053.         string = string.replace( /"/g, 'Ig==' );
  1054.         string = string.replace( /'/g, 'Jw==' );
  1055.         string = string.replace( /&/g, 'Jg==' );
  1056.         string = string.replace( /\//g, 'Lw==' );
  1057.         string = string.replace( /\+/g, 'Kw==' );
  1058.  
  1059.         return string;
  1060.     },
  1061.  
  1062.     decode: function( string ) {
  1063.         string = string.replace( /LA==/g, ',' );
  1064.         string = string.replace( /Ww==/g, '[' );
  1065.         string = string.replace( /XQ==/g, ']' );
  1066.         string = string.replace( /Ig==/g, '"' );
  1067.         string = string.replace( /Jw==/g, "'" );
  1068.         string = string.replace( /Jg==/g, '&' );
  1069.         string = string.replace( /Lw==/g, '/' );
  1070.         string = string.replace( /Kw==/g, '+' );
  1071.  
  1072.         return string;
  1073.     },
  1074.  
  1075.     _parseSep: function( url ) {
  1076.         var self = this,
  1077.             urlSep = null;
  1078.  
  1079.         if( typeof url == 'undefined' )
  1080.             url = self._url;
  1081.  
  1082.         if( ! self._options.smp.isInstalled || self._options.smp.disableConvertUrls ) {
  1083.             url     = self.parse_url( url );
  1084.             url     = url.scheme + '://' + url.host + (url.port ? ':'+url.port: '') + url.path;
  1085.             url     = url.split('&')[0];
  1086.         } else {
  1087.             url     = url.indexOf('?') > -1 ? url.split('?')[0] : url.split(';')[0];
  1088.         }
  1089.  
  1090.         urlSep  = {
  1091.             'f' : '?',
  1092.             'n' : '&'
  1093.         };
  1094.  
  1095.         return {
  1096.             url : url,
  1097.             urlSep : urlSep
  1098.         };
  1099.     },
  1100.  
  1101.     /**
  1102.      * Init content
  1103.      */
  1104.     _initContent: function() {
  1105.         var self = this;
  1106.  
  1107.         self._jqContent
  1108.             .css('position', 'relative');
  1109.     },
  1110.  
  1111.     /**
  1112.      * @return {scheme: 'http', host: 'hostname', user: 'username', pass: 'password', path: '/path', query: 'arg=value', fragment: 'anchor'}
  1113.      */
  1114.     parse_url: function(str, component) {
  1115.         var query, key = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port',
  1116.             'relative', 'path', 'directory', 'file', 'query', 'fragment'
  1117.             ],
  1118.             ini = (this.php_js && this.php_js.ini) || {},
  1119.             mode = (ini['phpjs.parse_url.mode'] &&
  1120.             ini['phpjs.parse_url.mode'].local_value) || 'php',
  1121.             parser = {
  1122.             php: /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
  1123.             strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
  1124.             loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // Added one optional slash to post-scheme to catch file:/// (should restrict this)
  1125.             };
  1126.  
  1127.         var m = parser[mode].exec(str),
  1128.             uri = {},
  1129.             i = 14;
  1130.         while (i--) {
  1131.             if (m[i]) {
  1132.             uri[key[i]] = m[i];
  1133.             }
  1134.         }
  1135.  
  1136.         if (component) {
  1137.             return uri[component.replace('PHP_URL_', '')
  1138.             .toLowerCase()];
  1139.         }
  1140.         if (mode !== 'php') {
  1141.             var name = (ini['phpjs.parse_url.queryKey'] &&
  1142.             ini['phpjs.parse_url.queryKey'].local_value) || 'queryKey';
  1143.             parser = /(?:^|&)([^&=]*)=?([^&]*)/g;
  1144.             uri[name] = {};
  1145.             query = uri[key[12]] || '';
  1146.             query.replace(parser, function($0, $1, $2) {
  1147.             if ($1) {
  1148.                 uri[name][$1] = $2;
  1149.             }
  1150.             });
  1151.         }
  1152.         delete uri.source;
  1153.         return uri;
  1154.     },
  1155.  
  1156.     baseTypes: function( skip ) {
  1157.         var self    = this,
  1158.             types   = [];
  1159.  
  1160.         function find( self ) {
  1161.             self._box.find('[data-base-type]').each(function(){
  1162.                 var baseType = jQuery(this).attr('data-base-type'),
  1163.                     type = jQuery(this).attr('data-type');
  1164.  
  1165.                 if( baseType == 'categories' ) {
  1166.                     baseType += ':' + type;
  1167.                 }
  1168.  
  1169.                 if( types.indexOf( baseType ) > -1 ) return;
  1170.                 if( typeof skip != 'undefined' && skip.indexOf( baseType ) > -1 ) return;
  1171.  
  1172.                 if( type == 'text' ) return;
  1173.  
  1174.                 types.push( baseType );
  1175.             });
  1176.         }
  1177.  
  1178.         find( self );
  1179.  
  1180.         for( var i = 0; i < MegaFilterINSTANCES.length; i++ ) {
  1181.             if( i == self._instanceIdx ) continue;
  1182.  
  1183.             find( MegaFilterINSTANCES[i] );
  1184.         }
  1185.  
  1186.         return types;
  1187.     },
  1188.  
  1189.     _ajaxUrl: function( url ) {
  1190.         if( this.parse_url( document.location.toString() ).scheme == 'https' && this.parse_url( url ).scheme == 'http' ) {
  1191.             url = url.replace( 'http://', 'https://' );
  1192.         }
  1193.  
  1194.         url = this.removeMfpFromUrl( url );
  1195.  
  1196.         var self = this,
  1197.             params = url.indexOf('?') > -1 ? url.split('?')[1] : '',
  1198.             parts = ( url.indexOf('?') > -1 ? url.split('?')[0] : url ).split('/');
  1199.  
  1200.         for( i = 0; i < parts.length; i++ ) {
  1201.             if( /^page-[0-9]+$/.test( parts[i] ) ) {
  1202.                 delete parts[i];
  1203.             } else if( i > 0 && /^[0-9]+$/.test( parts[i] ) && parts[i-1] == 'page' ) {
  1204.                 delete parts[i];
  1205.                 delete parts[i-1];
  1206.             }
  1207.         }
  1208.  
  1209.         url = parts.join('/');
  1210.         url = url.replace('://', '###URL###');
  1211.         url = url.replace( /\/+/g, '/' );
  1212.         url = url.replace('###URL###', '://');
  1213.  
  1214.         if( params != '' ) {
  1215.             url += '?' + params;
  1216.         }
  1217.  
  1218.         if( self._options.mijoshop ) {
  1219.             return url + ( url.indexOf('?') > -1 ? '&' : '?' ) + 'option=com_mijoshop&format=raw';
  1220.         }
  1221.  
  1222.         if( self._options.joo_cart != false ) {
  1223.             function parse( u ) {
  1224.                 u = u.replace( 'index.php', '' );
  1225.                 u = u.replace( /\/$/, '' );
  1226.  
  1227.                 return u + '/';
  1228.             }
  1229.  
  1230.             var site_url    = parse( self._options.joo_cart.site_url ),
  1231.                 main_url    = parse( self._options.joo_cart.main_url ),
  1232.                 route       = url.indexOf( 'index.php' ) > -1 ? self._parseUrl( url, {} ).route : url.replace( main_url, '' ),
  1233.                 query       = self.parse_url( url ).query;
  1234.  
  1235.             if( typeof route == 'undefined' ) {
  1236.                 route = '';
  1237.             }
  1238.  
  1239.             if( typeof query == 'undefined' ) {
  1240.                 query = '';
  1241.             }
  1242.  
  1243.             if( route.indexOf('?') > -1 ) {
  1244.                 route = route.split('?')[0];
  1245.             }
  1246.  
  1247.             if( route == 'module/mega_filter/getajaxinfo' ) {
  1248.                 return site_url + 'index.php?route=' + route + ( query ? '&' + query : '' ) + '&option=com_opencart&format=raw';
  1249.             }
  1250.         }
  1251.  
  1252.         return url;
  1253.     },
  1254.  
  1255.     _ajaxGetInfo: function( baseTypes, showLoader ){
  1256.         var self = this;
  1257.  
  1258.         if( showLoader ) {
  1259.             self._showLoader( true );
  1260.         }
  1261.  
  1262.         jQuery.ajax({
  1263.             'url'       : self._ajaxUrl( self.createUrl( self._options.ajaxGetInfoUrl, jQuery.extend( {}, self._params ), true ) ),
  1264.             'type'      : 'GET',
  1265.             'data'      : {
  1266.                 'mfilterIdx'    : self._options.idx,
  1267.                 'mfilterRoute'  : self._options.route,
  1268.                 'mfilterBTypes' : self.baseTypes( baseTypes ).join(','),
  1269.                 'mfilterLPath'  : self.locationPath()
  1270.             },
  1271.             'success'   : function( response ) {
  1272.                 var $tmp = jQuery('<tmp>').html( response );
  1273.  
  1274.                 if( showLoader ) {
  1275.                     self._hideLoader();
  1276.                 }
  1277.  
  1278.                 self._parseInfo( self.base64_decode($tmp.find('#mfilter-json').html()) );
  1279.             },
  1280.             'error'     : function() {
  1281.  
  1282.             }
  1283.         });
  1284.     },
  1285.  
  1286.     /**
  1287.      * Init info about counts
  1288.      */
  1289.     _initCountInfo: function() {
  1290.         var self = this;
  1291.  
  1292.         if( ! self._options.calculateNumberOfProducts || self._isInit )
  1293.             return;
  1294.  
  1295.         self._ajaxGetInfo(['categories:tree','categories:cat_checkbox','price']);
  1296.  
  1297.         self._parseInfo('{"stock_status":[],"manufacturers":[],"rating":[],"attributes":[],"options":[],"filters":[],"discounts":[]}',true);
  1298.     },
  1299.  
  1300.     _parseInfo: function( data, first ) {
  1301.         var self    = this,
  1302.             filters = self.filters(),
  1303.             json    = jQuery.parseJSON( data );
  1304.  
  1305.         for( var i in json ) {
  1306.             switch( i ) {
  1307.                 case 'categories:tree' : {
  1308.                     self._box.find('.mfilter-category-tree > ul > li').remove();
  1309.  
  1310.                     for( var j = 0; j < json[i].length; j++ ) {
  1311.                         if( self._options.hideInactiveValues && json[i][j].cnt == '0' ) continue;
  1312.  
  1313.                         self._box.find('.mfilter-category-tree > ul').append(jQuery('<li class="mfilter-tb-as-tr">')
  1314.                             .append(jQuery('<div class="mfilter-tb-as-td">')
  1315.                                 .append(jQuery('<a>')
  1316.                                     .attr('data-id', json[i][j].id)
  1317.                                     .attr('data-parent-id', json[i][j].pid)
  1318.                                     .html( json[i][j].name )
  1319.                                 )
  1320.                             )
  1321.                             .append('<div class="mfilter-tb-as-td mfilter-col-count"><span class="mfilter-counter">' + json[i][j].cnt + '</span></div>')
  1322.                         );
  1323.                     }
  1324.  
  1325.                     self._initTreeCategory( true );
  1326.  
  1327.                     break;
  1328.                 }
  1329.                 case 'categories:cat_checkbox' : {
  1330.                     var cnt = {};
  1331.  
  1332.                     for( var j in json[i] ) {
  1333.                         cnt[json[i][j].id] = json[i][j].cnt;
  1334.                     }
  1335.  
  1336.                     self._box.find('.mfilter-filter-item.mfilter-cat_checkbox').each(function(){
  1337.                         var $self = jQuery(this),
  1338.                             cx = 0,
  1339.                             idx = 0;
  1340.  
  1341.                         $self.find('input[value]').each(function(i){
  1342.                             var $self2 = $(this),
  1343.                                 $parent = $self2.parent().parent(),
  1344.                                 $cnt = $parent.find('.mfilter-counter'),
  1345.                                 checked = $self2.is(':checked'),
  1346.                                 id = $self2.val(),
  1347.                                 c = typeof cnt[id] == 'undefined' ? 0 : parseInt( cnt[id] ),
  1348.                                 ct = c;
  1349.  
  1350.                             if( typeof filters['path'] != 'undefined' ) {
  1351.                                 if( filters['path'].indexOf( encodeURIComponent( id ) ) == -1 ) {
  1352.                                     ct = '+' + ct;
  1353.                                 }
  1354.                             }
  1355.  
  1356.                             $cnt.text( ct )[checked?'addClass':'removeClass']('mfilter-close');
  1357.  
  1358.                             if( c ) {
  1359.                                 cx++;
  1360.                                 $parent.removeClass('mfilter-hide mfilter-first-child');
  1361.                             }
  1362.  
  1363.                             if( checked || c ) {
  1364.                                 $self2.removeAttr('disabled');
  1365.                                 $parent.removeClass('mfilter-disabled');
  1366.                             } else {
  1367.                                 $self2.attr('disabled',true);
  1368.                                 $parent.addClass('mfilter-disabled');
  1369.                             }
  1370.  
  1371.                             if( ! $parent.hasClass('mfilter-hide') ) {
  1372.                                 if( i > 0 && idx == 0 ) {
  1373.                                     $parent.addClass('mfilter-first-child');
  1374.                                 }
  1375.                                 idx++;
  1376.                             }
  1377.                         });
  1378.  
  1379.                         if( cx ) {
  1380.                             $self.removeClass('mfilter-hide');
  1381.                         }
  1382.                     });
  1383.  
  1384.                     break;
  1385.                 }
  1386.                 case 'price' : {
  1387.                     var priceRange = self.getPriceRange();
  1388.  
  1389.                     if( priceRange.min == self._options.priceMin && priceRange.max == self._options.priceMax ) {
  1390.                         self._box.find('[id="mfilter-opts-price-min"]').val( json[i].min );
  1391.                         self._box.find('[id="mfilter-opts-price-max"]').val( json[i].max );
  1392.                     }
  1393.  
  1394.                     self._options.priceMin = json[i].min;
  1395.                     self._options.priceMax = json[i].max;
  1396.  
  1397.                     self._refreshPrice();
  1398.  
  1399.                     break;
  1400.                 }
  1401.                 case 'vehicles' : {
  1402.                     self._box.find('.mfilter-filter-item.mfilter-vehicles').each(function(){
  1403.                         var $li = jQuery(this),
  1404.                             $prev = null,
  1405.                             auto_levels = $li.attr('data-auto-levels') == '1' ? true : false;
  1406.  
  1407.                         $li.find('select').each(function(i){
  1408.                             var keys    = [ 'makes', 'models', 'engines', 'years' ],
  1409.                                 vals    = typeof json['vehicles'][keys[i]] != 'undefined' ? json['vehicles'][keys[i]] : [],
  1410.                                 params  = typeof self.urlToFilters().vehicle != 'undefined' ? self.urlToFilters().vehicle.length : 0,
  1411.                                 $self   = jQuery(this),
  1412.                                 val     = '';//typeof self.urlToFilters().vehicle != 'undefined' ? self.urlToFilters().vehicle[i] : '';
  1413.  
  1414.                             if( typeof filters.vehicle != 'undefined' ) {
  1415.                                 val = filters.vehicle[i];
  1416.                             }
  1417.  
  1418.                             if( ( $prev == null || ! $prev.is(':disabled') ) && ( vals.length || params < i ) ) {
  1419.                                 $self.html( '<option value="">' + $self.find('option:first').text() + '</option>' );
  1420.  
  1421.                                 for( var j = 0; j < vals.length; j++ ) {
  1422.                                     $self.append(jQuery('<option>')
  1423.                                         .attr({
  1424.                                             'value' : vals[j].value,
  1425.                                             'id' : vals[j].key,
  1426.                                             'data-name' : vals[j].name,
  1427.                                             'data-total' : vals[j].total?vals[j].total:''
  1428.                                         })
  1429.                                         .attr(keys[i]=='makes'?{
  1430.                                             'data-image' : vals[j].image
  1431.                                         }:{})
  1432.                                         .text(vals[j].name)
  1433.                                         .attr('selected', val == vals[j].value)
  1434.                                     );
  1435.                                 }
  1436.  
  1437.                                 $self.attr('disabled',vals.length?false:true).mf_selectpicker('refresh');
  1438.                             } else {
  1439.                                 $self.attr('disabled',true).mf_selectpicker('refresh');
  1440.                             }
  1441.  
  1442.                             if( auto_levels ) {
  1443.                                 $self.parent()[i>0&&$self.is(':disabled')?'addClass':'removeClass']('mfilter-hide');
  1444.                             }
  1445.  
  1446.                             $prev = $self;
  1447.                         });
  1448.                     });
  1449.  
  1450.                     break;
  1451.                 }
  1452.                 case 'levels' : {
  1453.                     self._box.find('.mfilter-filter-item.mfilter-levels').each(function(){
  1454.                         var $li = jQuery(this),
  1455.                             labels = $li.attr('data-labels').split('||');
  1456.  
  1457.                         for( var i = 0; i < json['levels'].length; i++ ) {
  1458.                             var $select = $li.find('select:eq(' + i + ')'),
  1459.                                 vals = json['levels'][i],
  1460.                                 val = '';
  1461.  
  1462.                             if( typeof filters.level != 'undefined' ) {
  1463.                                 val = filters.level[i];
  1464.                             }
  1465.  
  1466.                             if( ! $select.length ) {
  1467.                                 $select = $('<select class="form-control">')
  1468.                                     .appendTo( $li.find('div.mfilter-levels') );
  1469.  
  1470.                                 $select.mf_selectpicker();
  1471.                             }
  1472.  
  1473.                             $select.html( '<option value="">' + ( typeof labels[i] == 'undefined' || labels[i] == '' ? ( vals.length && vals[0].label !== '' ? vals[0].label : '---' ) : labels[i] ) + '</option>' );
  1474.  
  1475.                             for( var j = 0; j < vals.length; j++ ) {
  1476.                                 $select.append(jQuery('<option>')
  1477.                                     .attr({
  1478.                                         'value' : vals[j].value,
  1479.                                         'id' : vals[j].key,
  1480.                                         'data-name' : vals[j].name,
  1481.                                         'data-total' : vals[j].total?vals[j].total:'',
  1482.                                         'data-image' : vals[j].image,
  1483.                                         'selected' : val == vals[j].value
  1484.                                     })
  1485.                                     .text( vals[j].name )
  1486.                                 );
  1487.                             }
  1488.  
  1489.                             if( vals.length ) {
  1490.                                 $select.removeAttr('disabled');
  1491.                             } else {
  1492.                                 $select.attr('disabled', true);
  1493.                             }
  1494.  
  1495.                             $select.mf_selectpicker('refresh');
  1496.                         }
  1497.  
  1498.                         if( $li.find('select').length >= json['levels'].length ) {
  1499.                             $li.find('select').each(function(i){
  1500.                                 if( i >= json['levels'].length ) {
  1501.                                     jQuery(this).parent().remove();
  1502.                                 }
  1503.                             });
  1504.                         }
  1505.  
  1506.                         if( $li.find('select').length ) {
  1507.                             self._initEvents();
  1508.                             $li.removeClass('mfilter-hide');
  1509.                         } else {
  1510.                             $li.addClass('mfilter-hide');
  1511.                         }
  1512.                     });
  1513.  
  1514.                     break;
  1515.                 }
  1516.                 case 'tags' :
  1517.                 case 'model' :
  1518.                 case 'sku' :
  1519.                 case 'upc' :
  1520.                 case 'ean' :
  1521.                 case 'jan' :
  1522.                 case 'isbn' :
  1523.                 case 'mpn' :
  1524.                 case 'location' :
  1525.                 case 'length' :
  1526.                 case 'width' :
  1527.                 case 'height' :
  1528.                 case 'weight' :
  1529.                 case 'rating' :
  1530.                 case 'attributes' :
  1531.                 case 'filters' :
  1532.                 case 'options' :
  1533.                 case 'discounts' :
  1534.                 case 'manufacturers' :
  1535.                 case 'stock_status' : {
  1536.                     self._box.find('.mfilter-filter-item.mfilter-' + i).each(function(){
  1537.                         var $item       = jQuery(this),
  1538.                             seo         = $item.attr('data-seo-name'),
  1539.                             id          = $item.attr('data-id'),
  1540.                             $items      = $item.find( '.mfilter-options .mfilter-option'),
  1541.                             hidden      = 0;
  1542.  
  1543.                         $items.each(function(){
  1544.                             var $self       = jQuery(this),
  1545.                                 $input      = $self.find('input[type=checkbox],input[type=radio],select'),
  1546.                                 val         = $input.val(),
  1547.                                 $counter    = jQuery(this).find('.mfilter-counter'),
  1548.                                 text        = '',
  1549.                                 cnt         = json[i];
  1550.  
  1551.                             if( id && typeof cnt[id] != 'undefined' ) {
  1552.                                 cnt = cnt[id];
  1553.                             }
  1554.  
  1555.                             if( $self.hasClass( 'mfilter-select' ) ) {
  1556.                                 var $options    = $input.find('option'),
  1557.                                     hOptions    = 0,
  1558.                                     val         = $input.val(),
  1559.                                     idx         = $input.prop('selectedIndex');
  1560.  
  1561.                                 if( typeof self._selectOptions[seo] == 'undefined' ) {
  1562.                                     self._selectOptions[seo] = [];
  1563.  
  1564.                                     $options.each(function(){
  1565.                                         self._selectOptions[seo].push({
  1566.                                             'name'  : jQuery(this).attr('data-name'),
  1567.                                             'id'    : jQuery(this).attr('id'),
  1568.                                             'value' : jQuery(this).attr('value'),
  1569.                                             'text'  : jQuery(this).html()
  1570.                                         });
  1571.                                     });
  1572.                                 }
  1573.  
  1574.                                 $options.remove();
  1575.  
  1576.                                 (function(){
  1577.                                     function add( $option ) {
  1578.                                         $input.append( $option );
  1579.  
  1580.                                         if( val == $option.val() ) {
  1581.                                             idx = $input.find('option').length-1;
  1582.                                         }
  1583.                                     }
  1584.  
  1585.                                     for( var i = 0; i < self._selectOptions[seo].length; i++ ) {
  1586.                                         var $option = jQuery('<option>')
  1587.                                             .attr('value', self._selectOptions[seo][i].value);
  1588.  
  1589.                                         if( self._selectOptions[seo][i].name ) {
  1590.                                             $option.attr('data-name', self._selectOptions[seo][i].name);
  1591.                                         }
  1592.  
  1593.                                         if( self._selectOptions[seo][i].id ) {
  1594.                                             $option.attr('id', self._selectOptions[seo][i].id);
  1595.                                         }
  1596.  
  1597.                                         if( self._selectOptions[seo][i].id ) {
  1598.                                             var idd = self._selectOptions[seo][i].id.split('-').pop();
  1599.  
  1600.                                             if( first || typeof cnt[idd] != 'undefined' ) {
  1601.                                                 $option.html( ( ! first && self._options.showNumberOfProducts ? '(' + cnt[idd] + ') ' : '' ) + self._selectOptions[seo][i].name );
  1602.  
  1603.                                                 add( $option );
  1604.                                             } else {
  1605.                                                 $option.attr('disabled', true).html( ( self._options.showNumberOfProducts ? '(0)' : '' ) + self._selectOptions[seo][i].name );
  1606.  
  1607.                                                 if( ! self._options.hideInactiveValues ) {
  1608.                                                     add( $option );
  1609.                                                 }
  1610.  
  1611.                                                 hOptions++;
  1612.                                             }
  1613.                                         } else {
  1614.                                             $option.html( self._selectOptions[seo][i].text );
  1615.                                             add( $option );
  1616.                                         }
  1617.                                     }
  1618.                                 })();
  1619.  
  1620.                                 if( idx >= 0 ) {
  1621.                                     $input.prop('selectedIndex', idx);
  1622.                                 }
  1623.  
  1624.                                 if( hOptions == self._selectOptions[seo].length ) {
  1625.                                     hidden++;
  1626.                                 }
  1627.                             } else if( $self.hasClass( 'mfilter-slider' ) ) {
  1628.                                 //if( self._options.hideInactiveValues ) {
  1629.                                     self._box.find('[data-id="' + id + '"][data-slider-id]').each(function(){
  1630.                                         var slider_id = jQuery(this).attr('data-slider-id'),
  1631.                                             data = {};
  1632.  
  1633.                                         for( var i in self._sliders[slider_id].data ) {
  1634.                                             if( typeof cnt != 'undefined' && typeof cnt[i] != 'undefined' && parseInt( cnt[i] ) > 0 ) {
  1635.                                                 data[i] = self._sliders[slider_id].data[i];
  1636.                                             }
  1637.                                         }
  1638.  
  1639.                                         self._sliders[slider_id].init( data, true );
  1640.                                     });
  1641.                                 //}
  1642.                             } else if( $self.hasClass( 'mfilter-text' ) ) {
  1643.                                 $input = $self.find('input[type=text]');
  1644.  
  1645.                                 if( typeof filters[seo] != 'undefined' ) {
  1646.  
  1647.                                 } else {
  1648.  
  1649.                                 }
  1650.                             } else {
  1651.                                 var idd = $input.attr('id').split('-').pop();
  1652.  
  1653.                                 if( typeof filters[seo] != 'undefined' ) {
  1654.                                     if( filters[seo].indexOf( encodeURIComponent( self.encode( val ) ) ) > -1 ) {
  1655.                                         $counter.addClass( 'mfilter-close' );
  1656.                                     } else {
  1657.                                         if( ! $item.hasClass( 'mfilter-radio' ) && ! $item.hasClass('mfilter-image_list_radio') /*&& base_type != 'option'*/ )
  1658.                                             text += '+';
  1659.  
  1660.                                         $counter.removeClass( 'mfilter-close' );
  1661.                                     }
  1662.                                 } else {
  1663.                                     $counter.removeClass( 'mfilter-close' );
  1664.                                 }
  1665.  
  1666.                                 $self.removeClass('mfilter-first-child mfilter-last-child mfilter-disabled mfilter-hide mfilter-visible');
  1667.                                 $self.parent().removeClass('mfilter-hide');
  1668.  
  1669.                                 if( typeof cnt[idd] != 'undefined' && parseInt( cnt[idd] ) > 0 ) {
  1670.                                     text += cnt[idd];
  1671.  
  1672.                                     $self.addClass('mfilter-visible');
  1673.                                     $input.attr('disabled', false);
  1674.                                 } else {
  1675.                                     text = '0';
  1676.                                     hidden++;
  1677.  
  1678.                                     $self.addClass('mfilter-disabled');
  1679.                                     $input.attr('disabled',true);
  1680.  
  1681.                                     if( first !== true && self._options.hideInactiveValues ) {
  1682.                                         $self.addClass('mfilter-hide');
  1683.  
  1684.                                         if( self._box.hasClass('mfilter-content_top') ) {
  1685.                                             $self.parent().addClass('mfilter-hide');
  1686.                                         }
  1687.                                     }
  1688.                                 }
  1689.  
  1690.                                 $counter.text( text );
  1691.                             }
  1692.                         });
  1693.  
  1694.                         if( first !== true && self._options.hideInactiveValues ) {
  1695.                             if( $item.hasClass('mfilter-select') ) {
  1696.                                 $item[$item.find('select option[value!=""]').length?'removeClass':'addClass']('mfilter-hide');
  1697.                             } else {
  1698.                                 $item[hidden==$items.length?'addClass':'removeClass']('mfilter-hide');
  1699.                                 $item.find('.mfilter-option').not('.mfilter-hide,.mfilter-hide-by-live-filter').first().addClass('mfilter-first-child');
  1700.                                 $item.find('.mfilter-option').not('.mfilter-hide,.mfilter-hide-by-live-filter').last().addClass('mfilter-last-child');
  1701.                             }
  1702.                         }
  1703.                     });
  1704.  
  1705.                     break;
  1706.                 }
  1707.             }
  1708.         }
  1709.  
  1710.         if( first !== true && ( self._options.hideInactiveValues || self._box.find('[data-display-live-filter!="0"]').length ) ) {
  1711.             for( var s = 0; s < self._scrolls.length; s++ ) {
  1712.                 self._scrolls[s].refresh();
  1713.             }
  1714.  
  1715.             for( var b = 0; b < self._buttonsMore.length; b++ ) {
  1716.                 self._buttonsMore[b].refresh();
  1717.             }
  1718.  
  1719.             for( var f = 0; f < self._liveFilters.length; f++ ) {
  1720.                 self._liveFilters[f].refresh();
  1721.             }
  1722.  
  1723.             if( self._relativeScroll != null ) {
  1724.                 self._relativeScroll.refresh();
  1725.             }
  1726.         }
  1727.  
  1728.         self._updateInlineHorizontal();
  1729.     },
  1730.  
  1731.     _initAlwaysSearch: function() {
  1732.         var self    = this;
  1733.  
  1734.         function search() {
  1735.             self._jqContent.find('[name^=filter_],[name=search],[name=category_id],[name=sub_category],[name=description]').each(function(){
  1736.                 var name    = jQuery(this).attr('name'),
  1737.                     value   = jQuery(this).val(),
  1738.                     type    = jQuery(this).attr('type');
  1739.  
  1740.                 if( [ 'checkbox', 'radio' ].indexOf( type ) > -1 && ! jQuery(this).is(':checked') )
  1741.                     value = '';
  1742.  
  1743.                 if( name ) {
  1744.                     self._inUrl[name] = value;
  1745.                     self._params[name] = value;
  1746.                 }
  1747.             });
  1748.  
  1749.             self.reload();
  1750.             //self.ajax();
  1751.         }
  1752.  
  1753.         jQuery('#button-search').unbind('click').click(function(e){
  1754.             e.preventDefault();
  1755.  
  1756.             search();
  1757.         });
  1758.  
  1759.         self._jqContent.find('input[name=filter_name],input[name=search]').unbind('keydown').unbind('keyup').bind('keydown', function(e){
  1760.             if( e.keyCode == 13 ) {
  1761.                 e.preventDefault();
  1762.  
  1763.                 search();
  1764.             }
  1765.         });
  1766.     },
  1767.  
  1768.     hexToRgb: function(str) {
  1769.         if ( /^#([0-9a-f]{3}|[0-9a-f]{6})$/ig.test(str) ) {
  1770.             var hex = str.substr(1);
  1771.             hex = hex.length == 3 ? hex.replace(/(.)/g, '$1$1') : hex;
  1772.             var rgb = parseInt(hex, 16);
  1773.             return [(rgb >> 16) & 255, (rgb >> 8) & 255, rgb & 255].join(',');
  1774.         }
  1775.  
  1776.         return '255,255,255';
  1777.     },
  1778.  
  1779.     _initAlwaysAjaxPagination: function(){
  1780.         var self = this;
  1781.  
  1782.         if( ! self._options.ajaxPagination ) return;
  1783.  
  1784.         self._jqContent.find('.pagination a').click(function(){
  1785.             var url = jQuery(this).attr('href'),
  1786.                 params = self._parseUrl( url );
  1787.  
  1788.             if( typeof params.page != 'undefined' ) {
  1789.                 self._ajaxPagination = params.page;
  1790.  
  1791.                 self.ajax( url );
  1792.  
  1793.                 return false;
  1794.             }
  1795.         });
  1796.     },
  1797.  
  1798.     __initLoader: function() {
  1799.         var color = this.hexToRgb(typeof this._options.color == 'undefined' ? '#ffffff' : this._options.color.loader_over_results);
  1800.  
  1801.         this._jqLoader = jQuery('<span class="mfilter-ajax-loader-container" style="cursor: wait; z-index: 100; margin: 0; padding: 0; position: absolute; text-align: center; background-color: rgba(' + color + ',0.7);"></span>')
  1802.             .prependTo( this._jqContent )
  1803.             .html( '<img src="catalog/view/theme/default/stylesheet/mf/images/ajax-loader.gif?v2" alt="" />' )
  1804.             .hide();
  1805.     },
  1806.  
  1807.     __initLoaderFilter: function() {
  1808.         var color = this.hexToRgb(typeof this._options.color == 'undefined' ? '#ffffff' : this._options.color.loader_over_filter);
  1809.  
  1810.         this._jqLoaderFilter = jQuery('<span style="cursor: wait; z-index: 10000; margin: 0; padding: 0; position: absolute; background-color: rgba(' + color + ',0.7);"></span>')
  1811.             .prependTo( this._box )
  1812.             .hide();
  1813.     },
  1814.  
  1815.     /**
  1816.      * Init displaying the list
  1817.      */
  1818.     _initDisplayItems: function() {
  1819.         var self = this,
  1820.             isContentTop = self._box.hasClass( 'mfilter-content_top' ),
  1821.             params = self.urlToFilters();
  1822.  
  1823.         self._box.find('.mfilter-filter-item').each(function(i){
  1824.             var _level0             = jQuery(this),
  1825.                 type                = _level0.attr('data-type'),
  1826.                 seo_name            = _level0.attr('data-seo-name'),
  1827.                 displayLiveFilter   = parseInt( _level0.attr('data-display-live-filter') ),
  1828.                 displayListOfItems  = _level0.attr('data-display-list-of-items');
  1829.  
  1830.             if( ! displayListOfItems ) {
  1831.                 displayListOfItems = self._options.displayListOfItems.type;
  1832.             }
  1833.  
  1834.             if( type == 'price' || type == 'rating' ) return;
  1835.  
  1836.             var wrapper = _level0.find('.mfilter-content-wrapper'),
  1837.                 content = _level0.find('> .mfilter-content-opts'),
  1838.                 heading = _level0.find('> .mfilter-heading'),
  1839.                 idx = null;
  1840.  
  1841.             if( ! isContentTop && heading.hasClass( 'mfilter-collapsed' ) ) {
  1842.                 if( typeof params[seo_name] == 'undefined' ) {
  1843.                     content.show();
  1844.                 }
  1845.             }
  1846.  
  1847.             if( displayListOfItems == 'scroll' ) {
  1848.                 if( type == 'tree' || ( wrapper.actual ? wrapper.actual( 'outerHeight', { includeMargin: true } ) : wrapper.outerHeight(true) ) > self._options.displayListOfItems.maxHeight-1 ) {
  1849.                     if( self._options.displayListOfItems.standardScroll || jQuery.browser && jQuery.browser.msie && jQuery.browser.version < 9 ) {
  1850.                         wrapper
  1851.                             .addClass('mfilter-scroll-standard')
  1852.                             .css({
  1853.                                 'max-height': self._options.displayListOfItems.maxHeight + 'px',
  1854.                                 'overflow-y': 'scroll'
  1855.                             });
  1856.                     } else {
  1857.                         wrapper
  1858.                             .attr('id', 'mfilter-content-opts-' + self._instanceIdx + '-' + i);
  1859.  
  1860.                         (function(){
  1861.                             if( type == 'slider' || type == 'text' || type == 'select' || type == 'vehicles' || type == 'levels' || type == 'price' ) return;
  1862.  
  1863.                             var init = false,
  1864.                                 $self = jQuery( '#mfilter-content-opts-' + self._instanceIdx + '-' + i );
  1865.  
  1866.                             idx = self._scrolls.length;
  1867.  
  1868.                             self._scrolls.push({
  1869.                                 refresh: function(){
  1870.                                     if( init ) return;
  1871.  
  1872.                                     init = true;
  1873.  
  1874.                                     $self.removeClass('scroll-wrapper').css('max-height', self._options.displayListOfItems.maxHeight+'px').scrollbar();
  1875.                                 }
  1876.                             });
  1877.  
  1878.                             if( ! self._options.calculateNumberOfProducts ) {
  1879.                                 self._scrolls[idx].refresh();
  1880.                             }
  1881.                         })();
  1882.                     }
  1883.                 }
  1884.             } else if( displayListOfItems == 'button_more' && ! isContentTop && type != 'image' && type != 'image_radio' ) {
  1885.                 self._buttonsMore.push((function( _level0 ){
  1886.                     function init( first ) {
  1887.                         var lessHeight  = 0,
  1888.                             $cnt        = _level0.find('.mfilter-options-container'),
  1889.                             moreHeight  = $cnt.actual ? $cnt.actual( 'outerHeight', { includeMargin: true } ) : $cnt.outerHeight(true),
  1890.                             show        = false,
  1891.                             count       = 0,
  1892.                             idx         = 0;
  1893.  
  1894.                         _level0.find('.mfilter-option.mfilter-tb-as-tr').each(function(i){
  1895.                             var _this = jQuery(this);
  1896.  
  1897.                             if( _this.hasClass('mfilter-hide') || _this.hasClass('mfilter-hide-by-live-filter') ) return;
  1898.  
  1899.                             if( idx < self._options.displayListOfItems.limit_of_items ) {
  1900.                                 lessHeight += _this.actual ? _this.actual( 'outerHeight', { includeMargin: true } ) : _this.outerHeight(true);
  1901.                             } else {
  1902.                                 count++;
  1903.                             }
  1904.  
  1905.                             idx++;
  1906.                         });
  1907.  
  1908.                         if( count ) {
  1909.                             wrapper.css('overflow','hidden').css('height', lessHeight+'px');
  1910.  
  1911.                             function sh( show, force ) {
  1912.                                 if( force ) {
  1913.                                     wrapper.height( moreHeight );
  1914.                                 } else {
  1915.                                     wrapper.animate({
  1916.                                         'height' : ! show ? moreHeight : lessHeight
  1917.                                     }, 500, function(){
  1918.                                         if( self._relativeScroll != null )
  1919.                                             self._relativeScroll.refresh();
  1920.                                     });
  1921.                                 }
  1922.  
  1923.                                 _level0.find('a.mfilter-button-more').text(show?self._options.displayListOfItems.textMore.replace( '%s', count ):self._options.displayListOfItems.textLess);
  1924.                             }
  1925.  
  1926.                             _level0.find('.mfilter-content-opts').append(jQuery('<div>')
  1927.                                 .addClass( 'mfilter-button-more' )
  1928.                                 .append(jQuery('<a>')
  1929.                                     .attr( 'href', '#' )
  1930.                                     .addClass( 'mfilter-button-more' )
  1931.                                     .text( self._options.displayListOfItems.textMore.replace( '%s', count ) )
  1932.                                     .bind('click', function(){
  1933.                                         sh( show );
  1934.  
  1935.                                         show = ! show;
  1936.  
  1937.                                         wrapper[show?'addClass':'removeClass']('mfilter-slide-down');
  1938.  
  1939.                                         return false;
  1940.                                     })
  1941.                                 )
  1942.                             );
  1943.  
  1944.                             if( wrapper.hasClass('mfilter-slide-down') ) {
  1945.                                 sh( false, true );
  1946.                                 show = true;
  1947.                             }
  1948.                         }
  1949.                     }
  1950.  
  1951.                     init( true );
  1952.  
  1953.                     idx = self._buttonsMore.length;
  1954.  
  1955.                     return {
  1956.                         refresh: function() {
  1957.                             _level0.find('.mfilter-content-wrapper').removeAttr('style');
  1958.                             _level0.find('.mfilter-button-more').remove();
  1959.  
  1960.                             init();
  1961.                         }
  1962.                     };
  1963.                 })( _level0 ));
  1964.             }
  1965.  
  1966.             if( type == 'cat_checkbox' ) {
  1967.                 (function(){
  1968.                     var cnt = 0;
  1969.  
  1970.                     content.find('.mfilter-category .mfilter-option').each(function(i){
  1971.                         if( jQuery(this).find('.mfilter-counter').text() != '0' ) {
  1972.                             if( i && ! cnt ) {
  1973.                                 jQuery(this).addClass('mfilter-first-child');
  1974.                             }
  1975.  
  1976.                             cnt++;
  1977.                         } else {
  1978.                             jQuery(this).addClass('mfilter-hide');
  1979.                         }
  1980.                     });
  1981.  
  1982.                     if( ! cnt ) {
  1983.                         _level0.addClass('mfilter-hide');
  1984.                     }
  1985.                 })();
  1986.             }
  1987.  
  1988.             (function(){
  1989.                 if( isContentTop ) {
  1990.                     return;
  1991.                 }
  1992.  
  1993.                 if( displayLiveFilter < 1 || content.find('.mfilter-option').length < displayLiveFilter || type == 'image' || type == 'image_radio' ) {
  1994.                     displayLiveFilter = 0;
  1995.  
  1996.                     return;
  1997.                 }
  1998.  
  1999.                 content.prepend('<div class="mfilter-live-filter"><input type="text" class="form-control" id="mfilter-live-filter-input-' + self._instanceIdx + '-' + i + '" /></div>');
  2000.  
  2001.                 wrapper.find('> .mfilter-options > div').attr('id', 'mfilter-live-filter-list-' + self._instanceIdx + '-' + i);
  2002.  
  2003.                 _level0.addClass('mfilter-live-filter-init');
  2004.  
  2005.                 jQuery('#mfilter-live-filter-list-' + self._instanceIdx + '-' + i).liveFilter('#mfilter-live-filter-input-'+self._instanceIdx + '-' + i, '.mfilter-visible,.mfilter-should-visible,.mfilter-disabled,.mfilter-option:not(.mfilter-filter-item)', {
  2006.                     'filterChildSelector' : 'label',
  2007.                     'after' : function(contains, containsNot){
  2008.                         var list = jQuery('#mfilter-live-filter-list-' + self._instanceIdx + '-' + i);
  2009.  
  2010.                         contains.removeClass('mfilter-should-visible').addClass('mfilter-visible');
  2011.                         containsNot.removeClass('mfilter-visible').addClass('mfilter-should-visible');
  2012.  
  2013.                         list.find('> .mfilter-option').removeClass('mfilter-first-child mfilter-last-child');
  2014.  
  2015.                         list.find('> .mfilter-option:not(.mfilter-hide):not(.mfilter-hide-by-live-filter):first').addClass('mfilter-first-child');
  2016.                         list.find('> .mfilter-option:not(.mfilter-hide):not(.mfilter-hide-by-live-filter):last').addClass('mfilter-last-child');
  2017.  
  2018.                         if( idx !== null ) {
  2019.                             if( displayListOfItems == 'scroll' ) {
  2020.                                 self._scrolls[idx].refresh();
  2021.                             } else if( displayListOfItems == 'button_more' ) {
  2022.                                 self._buttonsMore[idx].refresh();
  2023.                             }
  2024.                         }
  2025.  
  2026.                         if( self._relativeScroll != null ) {
  2027.                             self._relativeScroll.refresh();
  2028.                         }
  2029.                     }
  2030.                 });
  2031.  
  2032.                 _level0.addClass('mfilter-live-filter-init');
  2033.  
  2034.                 self._liveFilters.push({
  2035.                     refresh: function(){
  2036.                         content.find('.mfilter-live-filter')[content.find('.mfilter-option:not(.mfilter-hide)').length <= displayLiveFilter?'hide':'show']();
  2037.                     },
  2038.                     check: function() {
  2039.                         jQuery('#mfilter-live-filter-input-'+self._instanceIdx + '-' + i).trigger('keyup');
  2040.                     }
  2041.                 });
  2042.  
  2043.                 self._liveFilters[self._liveFilters.length-1].refresh();
  2044.             })();
  2045.  
  2046.             if( ! isContentTop && heading.hasClass( 'mfilter-collapsed' ) ) {
  2047.                 if( typeof params[seo_name] == 'undefined' ) {
  2048.                     content.hide();
  2049.                 }
  2050.             }
  2051.         });
  2052.     },
  2053.  
  2054.     /**
  2055.      * Init headers
  2056.      */
  2057.     _initHeading: function() {
  2058.         var self = this;
  2059.  
  2060.         if( self._box.hasClass('mfilter-content_top') )
  2061.             return;
  2062.  
  2063.         self._box.find('.mfilter-heading').click(function(){
  2064.             var opts = jQuery(this).parent().find('> .mfilter-content-opts');
  2065.  
  2066.             if( jQuery(this).hasClass('mfilter-collapsed') ) {
  2067.                 opts.slideDown('normal', function(){
  2068.                     if( self._relativeScroll != null )
  2069.                         self._relativeScroll.refresh();
  2070.                 });
  2071.                 jQuery(this).removeClass('mfilter-collapsed');
  2072.             } else {
  2073.                 opts.slideUp('normal', function(){
  2074.                     if( self._relativeScroll != null )
  2075.                         self._relativeScroll.refresh();
  2076.                 });
  2077.                 jQuery(this).addClass('mfilter-collapsed');
  2078.             }
  2079.         });
  2080.     },
  2081.  
  2082.     _updateInlineHorizontal: function() {
  2083.         for( var i = 0; i < this._inlineHorizontalUpdate.length; i++ ) {
  2084.             this._inlineHorizontalUpdate[i]();
  2085.         }
  2086.     },
  2087.  
  2088.     _initInlineHorizontal: function() {
  2089.         var self = this;
  2090.  
  2091.         if( ! self._box.hasClass( 'mfilter-content_top' ) ) {
  2092.             return;
  2093.         }
  2094.  
  2095.         self._box.find('li[data-inline-horizontal="1"][data-type="checkbox"],li[data-inline-horizontal="1"][data-type="radio"],li[data-inline-horizontal="1"][data-type="image_list_checkbox"],li[data-inline-horizontal="1"][data-type="image_list_radio"]').each(function(){
  2096.             var $container = jQuery(this).addClass('mfilter-inline-horizontal').find('.mfilter-opts-container'),
  2097.                 $wrapper = $container.find('> .mfilter-content-wrapper'),
  2098.                 $options = $wrapper.find('> .mfilter-options'),
  2099.                 $optionsCnt = $options.find('> .mfilter-options-container'),
  2100.                 $tb = $optionsCnt.find('> .mfilter-tb'),
  2101.                 left = 0;
  2102.  
  2103.             function width() {
  2104.                 var w = 0,
  2105.                     b = false;
  2106.  
  2107.                 left = 0;
  2108.  
  2109.                 $tb.find('> .mfilter-tb').each(function(){
  2110.                     var ww = jQuery(this).outerWidth(true);
  2111.  
  2112.                     if( self._lastEvent ) {
  2113.                         var $el = jQuery(this).find('[id="' + self._lastEvent + '"]');
  2114.  
  2115.                         if( $el.length ) {
  2116.                             b = true;
  2117.                         } else if( ! b ) {
  2118.                             left += ww;
  2119.                         }
  2120.                     }
  2121.  
  2122.                     w += ww;
  2123.                 });
  2124.  
  2125.                 return w;
  2126.             }
  2127.  
  2128.             self._inlineHorizontalUpdate[self._inlineHorizontalUpdate.length] = function() {
  2129.                 $optionsCnt.removeAttr('style');
  2130.                 $tb.removeAttr('style').css('margin-left',$tb.attr('data-mgr')+'px');
  2131.  
  2132.                 o1 = w1;
  2133.                 o2 = w2;
  2134.  
  2135.                 w1 = $optionsCnt.width()-2*8;
  2136.                 w2 = width();
  2137.  
  2138.                 $optionsCnt.css('width', w1);
  2139.                 $tb.css('width', w2+fix);
  2140.  
  2141.                 if( w2 > w1 ) {
  2142.                     $right.addClass('mf-active');
  2143.  
  2144.                     if( x >= w2-w1 && $left.hasClass('mf-active') ) {
  2145.                         t=0;
  2146.                         $right.trigger('click');
  2147.                     } else if( self._lastEvent ) {
  2148.                         var $el = $tb.find('[id="' + self._lastEvent + '"]');
  2149.  
  2150.                         if( $el.length ) {
  2151.                             var w = $el.parent().parent().parent().outerWidth(true);
  2152.  
  2153.                             if( x > left ) {
  2154.                                 t=0;
  2155.                                 x=left-w+w1;
  2156.                                 $left.trigger('click');
  2157.                             } else if( x+w1 < left+w ) {
  2158.                                 t=0;
  2159.                                 x=x+(w*2)-w1;
  2160.                                 $right.trigger('click');
  2161.                             }
  2162.                         }
  2163.                     }
  2164.                 } else {
  2165.                     t=x=0;
  2166.                     $left.addClass('mf-active').trigger('click');
  2167.                     $right.removeClass('mf-active');
  2168.                 }
  2169.  
  2170.                 /*if( ! $right.hasClass('mf-active') ) {
  2171.                     if( w2 > w1 ) {
  2172.                         //t=0;
  2173.                         $right.addClass('mf-active');//.trigger('click');
  2174.                     } else {
  2175.                         t=x=0;
  2176.                         $left.addClass('mf-active').trigger('click');
  2177.                         //$right.removeClass('mf-active');
  2178.                     }
  2179.                 } else {
  2180.                     if( w2 <= w1 ) {
  2181.                         $right.removeClass('mf-active');
  2182.                     }
  2183.                 }*/
  2184.             };
  2185.  
  2186.             var $left = jQuery('<a href="#"></a>'),
  2187.                 $right = jQuery('<a href="#"></a>');
  2188.  
  2189.             $wrapper.prepend(jQuery('<div class="mfilter-scroll-left"></div>').append($left));
  2190.             $wrapper.append(jQuery('<div class="mfilter-scroll-right"></div>').append($right));
  2191.  
  2192.             var w1 = $optionsCnt.width(),
  2193.                 w2 = width(),
  2194.                 o1 = -1,
  2195.                 o2 = -1,
  2196.                 x = 0,
  2197.                 fix = 50,
  2198.                 t = 'normal';
  2199.  
  2200.             if( w2 > w1 ) {
  2201.                 $right.addClass('mf-active');
  2202.             }
  2203.  
  2204.             $optionsCnt.css('width', w1);
  2205.             $tb.css('width', w2+fix).attr('data-mgr','0');
  2206.  
  2207.             $left.click(function(){
  2208.                 var $self = jQuery(this);
  2209.  
  2210.                 if( ! $self.hasClass('mf-active') ) return false;
  2211.  
  2212.                 x -= w1;
  2213.  
  2214.                 if( x <= 0 ) {
  2215.                     x = 0;
  2216.                     $self.removeClass('mf-active');
  2217.                 }
  2218.  
  2219.                 $tb.attr('data-mgr', -x).stop().animate({
  2220.                     'marginLeft' : -x
  2221.                 }, t);
  2222.  
  2223.                 t = 'normal';
  2224.  
  2225.                 $right.addClass('mf-active');
  2226.  
  2227.                 return false;
  2228.             });
  2229.             $right.click(function(){
  2230.                 var $self = jQuery(this);
  2231.  
  2232.                 if( ! $self.hasClass('mf-active') ) return false;
  2233.  
  2234.                 x += w1;
  2235.  
  2236.                 if( x >= w2-w1 ) {
  2237.                     x = w2-w1;
  2238.                     $self.removeClass('mf-active');
  2239.                 }
  2240.  
  2241.                 $tb.attr('data-mgr', -x).stop().animate({
  2242.                     'marginLeft' : -x
  2243.                 }, t);
  2244.  
  2245.                 t = 'normal';
  2246.  
  2247.                 $left.addClass('mf-active');
  2248.  
  2249.                 return false;
  2250.             });
  2251.         });
  2252.     },
  2253.  
  2254.     _initCategoryRelated: function() {
  2255.         var self    = this;
  2256.  
  2257.         self._box.find('.mfilter-filter-item.mfilter-related').each(function(){
  2258.             var $li         = jQuery(this),
  2259.                 seoName     = $li.attr('data-seo-name'),
  2260.                 autoLevels  = $li.attr('data-auto-levels'),
  2261.                 fields      = $li.find('select[data-type="category-related"]');
  2262.  
  2263.             fields.each(function(i){
  2264.                 if( ! autoLevels && i == fields.length - 1 ) {
  2265.                     jQuery(this).change(function(){
  2266.                         if( self._options['refreshResults'] != 'using_button' ) {
  2267.                             self.runAjax();
  2268.                         }
  2269.                     });
  2270.                 } else {
  2271.                     function eChange( $self, id ) {
  2272.                         var $this = $self.parent().attr('data-id', id),
  2273.                             labels = $this.parent().attr('data-labels').split('#|#');
  2274.  
  2275.                         $self.change(function(){
  2276.                             var cat_id = $self.val();
  2277.  
  2278.                             $next = $this.next().find('select');
  2279.                             $parent = $next.parent();
  2280.                             label = typeof labels[id+1] == 'undefined' ? $parent.attr('data-next-label') : labels[id+1];
  2281.  
  2282.                             if( cat_id ) {
  2283.                                 $next.html('<option value="">' + self._options.text.loading + '</option>');
  2284.                                 $next.prop('selectedIndex', 0);
  2285.  
  2286.                                 jQuery.post( self._ajaxUrl( self._options.ajaxGetCategoryUrl ), { 'cat_id' : cat_id }, function( response ){
  2287.                                     var data = jQuery.parseJSON( response );
  2288.  
  2289.                                     if( data.length && autoLevels ) {
  2290.                                         var $li = jQuery('<li>');
  2291.  
  2292.                                         $this.after( $li );
  2293.                                         $next = jQuery('<select>').appendTo( $li );
  2294.  
  2295.                                         if( ! label )
  2296.                                             label = MegaFilterLang.text_select;
  2297.  
  2298.                                         eChange( $next, id+1 );
  2299.                                     }
  2300.  
  2301.                                     $next.html('<option value="">' + label + '</option>');
  2302.                                     $next.prop('selectedIndex', 0);
  2303.  
  2304.                                     for( var i = 0; i < data.length; i++ ) {
  2305.                                         $next.append( '<option value="' + data[i].id + '">' + data[i].name + '</option>' );
  2306.                                     }
  2307.  
  2308.                                     if( autoLevels ) {
  2309.                                         if( ! data.length ) {
  2310.                                             if( self._options['refreshResults'] != 'using_button' ) {
  2311.                                                 self.runAjax();
  2312.                                             }
  2313.                                         }
  2314.                                     } else if( ! data.length ) {
  2315.                                         if( self._options['refreshResults'] != 'using_button' ) {
  2316.                                             self.runAjax();
  2317.                                         }
  2318.                                     }
  2319.                                 });
  2320.                             }
  2321.  
  2322.                             var $p = $parent;
  2323.  
  2324.                             while( $p.length ) {
  2325.                                 if( autoLevels ) {
  2326.                                     var $t = $p;
  2327.                                     $p = $p.next();
  2328.                                     $t.remove();
  2329.                                 } else {
  2330.                                     $p.find('select').prop('selectedIndex', 0).find('option[value!=""]').remove();
  2331.                                     $p = $p.next();
  2332.                                 }
  2333.                             }
  2334.  
  2335.                             if( ! cat_id ) {
  2336.                                 var beforeVal   = self.urlToFilters()[seoName],
  2337.                                     afterVal    = self.filters()[seoName];
  2338.  
  2339.                                 if( typeof beforeVal == 'undefined' )
  2340.                                     beforeVal = [-1];
  2341.  
  2342.                                 if( typeof afterVal == 'undefined' )
  2343.                                     afterVal = [-1];
  2344.  
  2345.                                 if( beforeVal.toString() != afterVal.toString() )
  2346.                                     self.runAjax();
  2347.                             }
  2348.                         });
  2349.                     }
  2350.  
  2351.                     eChange( jQuery(this), i );
  2352.                 }
  2353.             });
  2354.         });
  2355.     },
  2356.  
  2357.     renderSelectedFilters: function( init ){
  2358.         if( ! this._options.displaySelectedFilters ) return;
  2359.  
  2360.         var self = this,
  2361.             filters = self.filters(),
  2362.             list = [],
  2363.             i, j;
  2364.  
  2365.         self.eachInstances(function( self ){
  2366.             filters = $.extend(filters, self.filters());
  2367.         }, true);
  2368.  
  2369.         if( self._selectedFilters === null ) {
  2370.             self._selectedFilters = $('<div class="mfilter-selected-filters" data-idx="' + self._idx + '">').append('<div class="mfilter-selected-filters-cnt"></div>');
  2371.  
  2372.             if( self._jqContent.attr('class') ) {
  2373.                 self._selectedFilters.addClass( self._jqContent.attr('class') );
  2374.             }
  2375.  
  2376.             if( self._options.displaySelectedFilters == 'over_filter' ) {
  2377.                 self._box.find('> .mfilter-content:first').prepend( self._selectedFilters );
  2378.             } else {
  2379.                 self._jqContent.before( self._selectedFilters );
  2380.             }
  2381.         }
  2382.  
  2383.         if( ! init ) {
  2384.             self.eachInstances(function( self ){
  2385.                 self.renderSelectedFilters( true );
  2386.             }, true);
  2387.         }
  2388.  
  2389.         if( self._selectedFilters.attr('data-idx') != self._idx+'' ) return;
  2390.  
  2391.         function add( label, fn ) {
  2392.             list.push($('<a>').html('<span>'+label+'</span><span class="mfilter-close"><i></i></span>').click(function(){
  2393.                 fn();
  2394.  
  2395.                 return false;
  2396.             }));
  2397.         }
  2398.  
  2399.         for( i in filters ) {
  2400.             (function($li){
  2401.                 var txt = $.trim( $li.find('.mfilter-heading-text span').html() ),
  2402.                     type = $li.attr('data-type'),
  2403.                     baseType = $li.attr('data-base-type');
  2404.  
  2405.                 if( txt !== '' ) {
  2406.                     txt += ': ';
  2407.                 }
  2408.  
  2409.                 switch( true ) {
  2410.                     case type == 'slider' : {
  2411.                         (function( $inputs ){
  2412.                             var $min = $inputs.find('.mfilter-opts-slider-min'),
  2413.                                 $max = $inputs.find('.mfilter-opts-slider-max');
  2414.  
  2415.                             if( $min.attr('data-key') != $min.attr('data-min') || $max.attr('data-key') != $max.attr('data-max') ) {
  2416.                                 add(txt + $min.val() + ' - ' + $max.val(), function(){
  2417.                                     self._sliders[$li.attr('data-slider-id')].resetValues();
  2418.  
  2419.                                     self.runAjax();
  2420.                                 });
  2421.                             }
  2422.                         })( $li.find('.mfilter-slider-inputs') );
  2423.  
  2424.                         break;
  2425.                     }
  2426.                     case type == 'price' : {
  2427.                         (function( $inputs ){
  2428.                             var $min = $inputs.find('#mfilter-opts-price-min'),
  2429.                                 $max = $inputs.find('#mfilter-opts-price-max');
  2430.  
  2431.                             if( $min.val() != self._options.priceMin || $max.val() != self._options.priceMax ) {
  2432.                                 add(txt + $min.val() + ' - ' + $max.val(), function(){
  2433.                                     $min.val( self._options.priceMin );
  2434.                                     $max.val( self._options.priceMax );
  2435.                                     $li.find('[id="mfilter-price-slider"]').each(function(){
  2436.                                         jQuery(this).slider( 'option', 'min', self._options.priceMin );
  2437.                                         jQuery(this).slider( 'option', 'max', self._options.priceMax );
  2438.                                         jQuery(this).slider( 'option', 'values', [ self._options.priceMin, self._options.priceMax ] );
  2439.                                         jQuery(this).slider( 'value', jQuery(this).slider('value') );
  2440.                                     });
  2441.  
  2442.                                     self.runAjax();
  2443.                                 });
  2444.                             }
  2445.                         })( $li.find('.mfilter-price-inputs') );
  2446.  
  2447.                         break;
  2448.                     }
  2449.                     case type == 'search' :
  2450.                     case type == 'text' : {
  2451.                         (function( $input ){
  2452.                             add(txt + $input.val(), function(){
  2453.                                 $input.val('').trigger('resetvalue');
  2454.  
  2455.                                 self.runAjax();
  2456.                             });
  2457.                         })( $li.find('input[type=text]') );
  2458.  
  2459.                         break;
  2460.                     }
  2461.                     case type == 'levels' :
  2462.                     case type == 'select' :
  2463.                     case type == 'vehicles' : {
  2464.                         $li.find('select').each(function(){
  2465.                             var $this = $(this);
  2466.  
  2467.                             if( $this.val() ) {
  2468.                                 $this.find('option:first').each(function(){
  2469.                                     if( $(this).text().replace(/-+/, '') !== '' ) {
  2470.                                         txt = $(this).text() + ': ';
  2471.                                     }
  2472.                                 });
  2473.  
  2474.                                 var $option = $this.find('option[value="' + $this.val() + '"]');
  2475.  
  2476.                                 add( $option.attr('data-name')?txt + $option.attr('data-name'):txt + $option.text(), function(){
  2477.                                     $this.prop('selectedIndex',0).trigger('change');
  2478.  
  2479.                                     if( self._options['refreshResults'] == 'using_button' ) {
  2480.                                         self.runAjax();
  2481.                                     }
  2482.                                 });
  2483.                             }
  2484.                         });
  2485.  
  2486.                         break;
  2487.                     }
  2488.                     default : {
  2489.                         function findInput( val ) {
  2490.                             var $input = $li.find('input[value="' + val.replace( /"/g, '&quot;' ) + '"]');
  2491.  
  2492.                             if( $input.length == 0 ) {
  2493.                                 $li.find('input').each(function(){
  2494.                                     if( $(this).val() == val ) {
  2495.                                         $input = $(this); return true;
  2496.                                     }
  2497.                                 });
  2498.                             }
  2499.  
  2500.                             return $input;
  2501.                         }
  2502.  
  2503.                         for( j = 0; j < filters[i].length; j++ ) {
  2504.                             var val = self.decode( decodeURIComponent( filters[i][j] ) );
  2505.  
  2506.                             switch( true ) {
  2507.                                 case ( type == 'checkbox' || type == 'radio' || type == 'image_list_radio' || type == 'image_list_checkbox' || type == 'rating' || type == 'cat_checkbox' ) : {
  2508.                                     (function( $input ){
  2509.                                         if( ! $input.length ) return;
  2510.  
  2511.                                         add(txt + $input.parent().next().html(), function(){
  2512.                                             $input.prop('checked', false).trigger('change');
  2513.  
  2514.                                             if( self._options['refreshResults'] == 'using_button' ) {
  2515.                                                 self.runAjax();
  2516.                                             }
  2517.                                         });
  2518.                                     })( findInput( val ) );
  2519.  
  2520.                                     break;
  2521.                                 }
  2522.                                 case ( type == 'image' || type == 'image_radio' ) && ( baseType == 'attribute' || baseType == 'option' ) : {
  2523.                                     (function( $input ){
  2524.                                         if( ! $input.length ) return;
  2525.  
  2526.                                         add(txt + $input.next().attr('title'), function(){
  2527.                                             $input.prop('checked', false).trigger('change');
  2528.  
  2529.                                             if( self._options['refreshResults'] == 'using_button' ) {
  2530.                                                 self.runAjax();
  2531.                                             }
  2532.                                         });
  2533.                                     })( findInput( val ) );
  2534.  
  2535.                                     break;
  2536.                                 }
  2537.                             }
  2538.                         }
  2539.                     }
  2540.                 }
  2541.             })( self._box.find('[data-seo-name="' + i + '"]') );
  2542.         }
  2543.  
  2544.         var $cnt = self._selectedFilters.find('> div').html('');
  2545.  
  2546.         self._selectedFilters[list.length?'show':'hide']();
  2547.  
  2548.         for( i = 0; i < list.length; i++ ) {
  2549.             $cnt.append( list[i] );
  2550.         }
  2551.     },
  2552.  
  2553.     _initSelectedFilters: function(){
  2554.         this.renderSelectedFilters( true );
  2555.     },
  2556.  
  2557.     /**
  2558.      * Init events
  2559.      */
  2560.     _initEvents: function() {
  2561.         var self = this;
  2562.  
  2563.         function val( $input ) {
  2564.             var val = $input.val(),
  2565.                 parent = $input.parent().parent();
  2566.  
  2567.             if( $input.attr('type') == 'checkbox' || $input.attr('type') == 'radio' ) {
  2568.                 parent.find('.mfilter-counter').unbind('click').bind('click', function(){
  2569.                     if( ! jQuery(this).hasClass( 'mfilter-close' ) ) return;
  2570.  
  2571.                     $input.prop('checked', false).trigger('change');
  2572.                 });
  2573.  
  2574.                 val = $input.is(':checked');
  2575.  
  2576.                 if( ! self._options.calculateNumberOfProducts ) {
  2577.                     if( self._isInit && $input.attr('type') == 'radio' ) {
  2578.                         parent.parent().find('.mfilter-counter').removeClass('mfilter-close');
  2579.                     }
  2580.  
  2581.                     parent.find('.mfilter-counter')[val?'addClass':'removeClass']('mfilter-close');
  2582.                 }
  2583.  
  2584.                 if( $input.attr('type') == 'radio' ) {
  2585.                     parent.parent().parent().parent().parent().parent().parent().find('.mfilter-input-active').removeClass('mfilter-input-active');
  2586.                 }
  2587.             }
  2588.  
  2589.             parent[val?'addClass':'removeClass']('mfilter-input-active');
  2590.         }
  2591.  
  2592.         self._box.find('input[type=checkbox],input[type=radio],select:not([data-type="category-related"])').unbind('change').change(function(){
  2593.             var type = jQuery(this).attr('data-type');
  2594.  
  2595.             if( type && ( type.split('-')[0] == 'vehicle' || type.split('-')[0] == 'level' ) ) {
  2596.                 var reset = false;
  2597.  
  2598.                 jQuery(this).parent().parent().find('select').each(function(){
  2599.                     if( reset ) {
  2600.                         jQuery(this).html( '<option value="">' + jQuery(this).find('option:first').text() + '</option>' ).prop('selectedIndex',0).mf_selectpicker('refresh');
  2601.                     } else if( jQuery(this).attr('data-type') == type ) {
  2602.                         reset = true;
  2603.                     }
  2604.                 });
  2605.             }
  2606.  
  2607.             self._lastEvent = jQuery(this).attr('id');
  2608.  
  2609.             if( self._options['refreshResults'] != 'using_button' ) {
  2610.                 self.runAjax();
  2611.             }
  2612.  
  2613.             val(jQuery(this));
  2614.  
  2615.             if( type && ( type.split('-')[0] == 'vehicle' || type.split('-')[0] == 'level' ) && type.split('-')[1] != 'years' && self._options['refreshResults'] == 'using_button' ) {
  2616.                 self._ajaxGetInfo([], true);
  2617.             }
  2618.         });
  2619.  
  2620.         self._box.find('.mfilter-options .mfilter-option input[type=checkbox]:checked,.mfilter-options .mfilter-option input[type=radio]:checked').each(function(){
  2621.             val(jQuery(this));
  2622.         });
  2623.  
  2624.         self._box.find('.mfilter-button a').bind('click', function(){
  2625.             self._lastEvent = null;
  2626.  
  2627.             if( jQuery(this).hasClass( 'mfilter-button-reset' ) ) {
  2628.                 self.eachInstances(function( self ){
  2629.                     self.resetFilters();
  2630.                 });
  2631.             }
  2632.  
  2633.             self.ajax();
  2634.  
  2635.             // On 2017-05-17 kanenas said:  We would like this to close again please...
  2636.             jQuery('.mfilter-free-container').addClass('mfilter-free-container-closed knns-mfilter').removeClass('mfilter-free-container-opened');
  2637.  
  2638.             return false;
  2639.         });
  2640.     },
  2641.  
  2642.     /**
  2643.      * Run ajax
  2644.      */
  2645.     runAjax: function() {
  2646.         var self = this;
  2647.  
  2648.         switch( self._options['refreshResults'] ) {
  2649.             case 'using_button' :
  2650.             case 'immediately' : {
  2651.                 self.ajax();
  2652.  
  2653.                 break;
  2654.             }
  2655.             case 'with_delay' : {
  2656.                 if( self._timeoutAjax )
  2657.                     clearTimeout( self._timeoutAjax );
  2658.  
  2659.                 self._timeoutAjax = setTimeout(function(){
  2660.                     self.ajax();
  2661.  
  2662.                     self._timeoutAjax = null;
  2663.                 }, self._options['refreshDelay'] );
  2664.  
  2665.                 break;
  2666.             }
  2667.         }
  2668.     },
  2669.  
  2670.     /**
  2671.      * Get the current price range
  2672.      */
  2673.     getPriceRange: function() {
  2674.         var self        = this,
  2675.             minInput    = self._box.find('[id="mfilter-opts-price-min"]'),
  2676.             maxInput    = self._box.find('[id="mfilter-opts-price-max"]'),
  2677.             min         = minInput.val(),
  2678.             max         = maxInput.val();
  2679.  
  2680.         if( ! /^[0-9]+$/.test( min ) || min < self._options.priceMin )
  2681.             min = self._options.priceMin;
  2682.  
  2683.         if( ! /^[0-9]+$/.test( max ) || max > self._options.priceMax )
  2684.             max = self._options.priceMax;
  2685.  
  2686.         return {
  2687.             min : parseInt( min ),
  2688.             max : parseInt( max )
  2689.         };
  2690.     },
  2691.  
  2692.     /**
  2693.      * Init price range
  2694.      */
  2695.     _initPrice: function() {
  2696.         var self        = this,
  2697.             priceRange  = self.getPriceRange(),
  2698.             filters     = self.urlToFilters(),
  2699.             minInput    = self._box.find('[id="mfilter-opts-price-min"]').unbind('change').bind('change', function(){
  2700.                 changePrice();
  2701.             }).val( filters.price ? filters.price[0] : priceRange.min ),
  2702.             maxInput    = self._box.find('[id="mfilter-opts-price-max"]').unbind('change').bind('change', function(){
  2703.                 changePrice();
  2704.             }).val( filters.price ? filters.price[1] : priceRange.max ),
  2705.             slider      = self._box.find('[id="mfilter-price-slider"]');
  2706.  
  2707.         self._refreshPrice = function( minMax ) {
  2708.             var priceRange = self.getPriceRange();
  2709.  
  2710.             if( priceRange.min < self._options.priceMin ) {
  2711.                 priceRange.min = self._options.priceMin;
  2712.             }
  2713.  
  2714.             if( priceRange.max > self._options.priceMax ) {
  2715.                 priceRange.max = self._options.priceMax;
  2716.             }
  2717.  
  2718.             if( priceRange.min > priceRange.max ) {
  2719.                 priceRange.min = priceRange.max;
  2720.             }
  2721.  
  2722.             if( priceRange.min.toString() != minInput.val() ) {
  2723.                 minInput.val( priceRange.min );
  2724.             }
  2725.  
  2726.             if( priceRange.max.toString() != maxInput.val() ) {
  2727.                 maxInput.val( priceRange.max );
  2728.             }
  2729.  
  2730.             slider.slider( 'option', 'values', [ priceRange.min, priceRange.max ] );
  2731.  
  2732.             if( minMax !== false ) {
  2733.                 slider.slider( 'option', 'min', self._options.priceMin );
  2734.                 slider.slider( 'option', 'max', self._options.priceMax );
  2735.                 slider.slider( 'value', slider.slider('value') );
  2736.             }
  2737.         };
  2738.  
  2739.         function changePrice() {
  2740.             self._refreshPrice( false );
  2741.  
  2742.             if( self._options['refreshResults'] != 'using_button' ) {
  2743.                 self.runAjax();
  2744.             }
  2745.         }
  2746.  
  2747.         slider.slider({
  2748.             range   : true,
  2749.             min     : self._options.priceMin ,
  2750.             max     : self._options.priceMax,
  2751.             values  : [ priceRange.min, priceRange.max ],
  2752.             isRTL   : self._options.direction == 'rtl',
  2753.             slide   : function( e, ui ) {
  2754.                 minInput.val( ui.values[0] );
  2755.                 maxInput.val( ui.values[1] );
  2756.             },
  2757.             stop    : function( e, ui ) {
  2758.                 if( self._options['refreshResults'] != 'using_button' )
  2759.                     self.runAjax();
  2760.             }
  2761.         });
  2762.     },
  2763.  
  2764.     _initWindowOnPopState: function(){
  2765.         var self = this,
  2766.             inited = false;
  2767.  
  2768.         if( self._isInit ) return;
  2769.  
  2770.         function update() {
  2771.             self.eachInstances(function( self ){
  2772.                 self._urlToFilters = null;
  2773.                 self.initUrls();
  2774.                 self.setFiltersByUrl();
  2775.             });
  2776.         }
  2777.  
  2778.         function setFilters( url ) {
  2779.             var params = self._parseUrl( url );
  2780.  
  2781.             if( typeof params.mfp != 'undefined' ) {
  2782.                 self.setFiltersByUrl( self.__urlToFilters( decodeURIComponent( params.mfp ) ) );
  2783.             } else {
  2784.                 self.resetFilters();
  2785.             }
  2786.         }
  2787.  
  2788.         // delay due Safari
  2789.         jQuery().ready(function(){
  2790.             setTimeout(function(){
  2791.                 inited = true;
  2792.             },1000);
  2793.         });
  2794.  
  2795.         window.onpopstate = function(e){
  2796.             if( ! inited ) return;
  2797.  
  2798.             if( e.state ) {
  2799.                 update();
  2800.  
  2801.                 self._render( e.state.html, e.state.json, true );
  2802.  
  2803.                 setFilters( e.state.url );
  2804.                 self.renderSelectedFilters();
  2805.             } else if( typeof self._cache.mainContent[self.location()] != 'undefined' && self._history > 0 ) {
  2806.                 update();
  2807.  
  2808.                 self._render( self._cache.mainContent[self.location()].html, self._cache.mainContent[self.location()].json, true );
  2809.  
  2810.                 setFilters( self.location() );
  2811.                 self.renderSelectedFilters();
  2812.             } else if( self._changed && self._history > 0 ) {
  2813.                 setFilters( self._startUrl.toString() );
  2814.  
  2815.                 self.ajax( null, true );
  2816.             } else {
  2817.                 update();
  2818.  
  2819.                 setFilters( self.location() );
  2820.  
  2821.                 self.ajax( null, true );
  2822.             }
  2823.  
  2824.             self._history--;
  2825.         };
  2826.     },
  2827.  
  2828.     count: function( obj ) {
  2829.         var c = 0;
  2830.  
  2831.         for( var i in obj ) {
  2832.             c++;
  2833.         }
  2834.  
  2835.         return c;
  2836.     },
  2837.  
  2838.     _initVehicles: function() {
  2839.         var self = this;
  2840.  
  2841.         self._box.find('li[data-type="vehicles"]').each(function(){
  2842.             var $li = jQuery(this),
  2843.                 auto_levels = $li.attr('data-auto-levels')=='1'?true:false;
  2844.  
  2845.             $li.find('select').each(function(i){
  2846.                 var $self = jQuery(this);
  2847.  
  2848.                 if( $self.find('option').length == 1 ) {
  2849.                     $self.attr('disabled',true).mf_selectpicker('refresh');
  2850.  
  2851.                     if( auto_levels && i > 0 ) {
  2852.                         $self.parent().addClass('mfilter-hide');
  2853.                     }
  2854.                 }
  2855.             });
  2856.         });
  2857.     },
  2858.  
  2859.     _initLevels: function() {
  2860.         var self = this;
  2861.  
  2862.         self._box.find('li[data-type="levels"]').each(function(){
  2863.             var $li = jQuery(this);
  2864.  
  2865.             $li.find('select').each(function(i){
  2866.                 var $self = jQuery(this);
  2867.  
  2868.                 if( $self.find('option').length == 1 ) {
  2869.                     $self.attr('disabled',true).mf_selectpicker('refresh');
  2870.  
  2871.                     if( i > 0 ) {
  2872.                         $self.parent().addClass('mfilter-hide');
  2873.                     }
  2874.                 }
  2875.             });
  2876.         });
  2877.     },
  2878.  
  2879.     setFiltersByUrl: function( params ) {
  2880.         var self    = this;
  2881.  
  2882.         if( typeof params == 'undefined' ) {
  2883.             params = self.urlToFilters();
  2884.         }
  2885.  
  2886.         self.resetFilters();
  2887.  
  2888.         self._box.find('li[data-type]').each(function(){
  2889.             var _this   = jQuery(this),
  2890.                 type    = _this.attr('data-type'),
  2891.                 seoName = type == 'tree' || type == 'cat_checkbox' ? 'path' : _this.attr('data-seo-name'),
  2892.                 value   = params[seoName];
  2893.  
  2894.             if( typeof value == 'undefined' || typeof value[0] == 'undefined' )
  2895.                 return;
  2896.  
  2897.             switch( type ) {
  2898.                 case 'tree' : {
  2899.                     _this.find('input[name=path]').val( value.join('_') );
  2900.  
  2901.                     break;
  2902.                 }
  2903.                 case 'cat_checkbox' :
  2904.                 case 'rating' :
  2905.                 case 'stock_status' :
  2906.                 case 'manufacturers' :
  2907.                 case 'discounts' :
  2908.                 case 'image' :
  2909.                 case 'image_radio' :
  2910.                 case 'radio' :
  2911.                 case 'image_list_radio' :
  2912.                 case 'image_list_checkbox' :
  2913.                 case 'checkbox' : {
  2914.                     for( var i in value ) {
  2915.                         if( typeof value[i] == 'function' ) continue;
  2916.  
  2917.                         if( type == 'image_radio' || type == 'radio' || type == 'image_list_radio' ) {
  2918.                             _this.find('.mfilter-image-checked').removeClass('mfilter-image-checked');
  2919.                         }
  2920.  
  2921.                         var val = self.decode( decodeURIComponent( value[i] ) ),
  2922.                             $p1 = _this.find('input[value="' + val.replace( /"/g, '&quot;' ) + '"]');
  2923.  
  2924.                         if( $p1.length == 0 ) {
  2925.                             _this.find('input').each(function(){
  2926.                                 if( $(this).val() == val ) {
  2927.                                     $p1 = $(this); return true;
  2928.                                 }
  2929.                             });
  2930.                         }
  2931.  
  2932.                         $p1 = $p1.prop('checked', true)
  2933.                             .parent();
  2934.  
  2935.                         $p1.parent()
  2936.                             .addClass('mfilter-input-active').find('.mfilter-counter').addClass('mfilter-close');
  2937.  
  2938.                         if( $p1.hasClass( 'mfilter-image' ) ) {
  2939.                             $p1.addClass('mfilter-image-checked');
  2940.                         }
  2941.                     }
  2942.  
  2943.                     break;
  2944.                 }
  2945.                 case 'levels' :
  2946.                 case 'vehicles' : {
  2947.                     _this.find('select').each(function(i){
  2948.                         if( typeof value[i] != 'undefined' ) {
  2949.                             jQuery(this).find('option').each(function(j){
  2950.                                 if( value[i] == jQuery(this).val() ) {
  2951.                                     jQuery(this).parent().prop('selectedIndex',j).mf_selectpicker('refresh');
  2952.  
  2953.                                     return false;
  2954.                                 }
  2955.                             });
  2956.                         }
  2957.                     });
  2958.  
  2959.                     break;
  2960.                 }
  2961.                 case 'select' : {
  2962.                     _this.find('select option[value="' + self.decode( decodeURIComponent( value[0] ) ).replace( /"/g, '&quot;' ) + '"]').attr('selected', true);
  2963.  
  2964.                     _this.find('select.mf_selectpicker').mf_selectpicker('refresh');
  2965.  
  2966.                     break;
  2967.                 }
  2968.                 case 'price' : {
  2969.                     if( typeof value[0] != 'undefined' && typeof value[1] != 'undefined' ) {
  2970.                         _this.find('input[id="mfilter-opts-price-min"]').val( value[0] );
  2971.                         _this.find('input[id="mfilter-opts-price-max"]').val( value[1] );
  2972.  
  2973.                         _this.find('[id="mfilter-price-slider"]').each(function(){
  2974.                             //jQuery(this).slider( 'option', 'min', value[0] );
  2975.                             //jQuery(this).slider( 'option', 'max', value[1] );
  2976.                             jQuery(this).slider( 'option', 'values', [ value[0], value[1] ] );
  2977.                             jQuery(this).slider( 'value', jQuery(this).slider('value') );
  2978.                         });
  2979.                     }
  2980.  
  2981.                     break;
  2982.                 }
  2983.                 case 'text' :
  2984.                 case 'search' : {
  2985.                     _this.find('input').val( self.decode( decodeURIComponent( value[0] ) ) );
  2986.  
  2987.                     break;
  2988.                 }
  2989.             }
  2990.         });
  2991.  
  2992.         for( var i = 0; i < self._sliders.length; i++ ) {
  2993.             self._sliders[i].setValues();
  2994.         }
  2995.     },
  2996.  
  2997.     /**
  2998.      * Show loader
  2999.      */
  3000.     _showLoader: function( forceOverFilter ) {
  3001.         var self = this;
  3002.  
  3003.         // kanenas: use the following for debugging
  3004.         //str = JSON.stringify(self._jqContent.find('.product-list'), null, 4);
  3005.         //console.log("j=" + str);
  3006.  
  3007.         if( self._jqLoader == null && ( forceOverFilter !== true || self._options.showLoaderOverResults ) ) {
  3008.             self.__initLoader();
  3009.         }
  3010.  
  3011.         if( self._jqLoaderFilter == null && ( forceOverFilter === true || self._options.showLoaderOverFilter ) ) {
  3012.             self.__initLoaderFilter();
  3013.         }
  3014.  
  3015.         if( forceOverFilter !== true && self._options.showLoaderOverResults ) {
  3016.             (function(){
  3017.                 var w = self._jqContent.outerWidth(),
  3018.                     h = self._jqContent.outerHeight(),
  3019.                     j = self._jqContent.find('.product-list'),
  3020.                     k = j.length ? j : self._jqContent.find('.product-grid'),
  3021.                     l = k.length ? k : self._jqContent,
  3022.                     t = k.length ? k.offset().top - 150 : l.offset().top;
  3023.  
  3024.                 self._jqLoader
  3025.                     .css('width', w + 'px')
  3026.                     .css('height', h + 'px')
  3027.                     .fadeTo('normal', 1)
  3028.                     .find('img')
  3029.                     .css('margin-top', t + 'px');
  3030.             })();
  3031.         }
  3032.  
  3033.         if( forceOverFilter === true || self._options.showLoaderOverFilter ) {
  3034.             (function(){
  3035.                 var w = self._box.outerWidth(),
  3036.                     h = self._box.outerHeight();
  3037.  
  3038.                 self._jqLoaderFilter
  3039.                     .css('width', w + 'px')
  3040.                     .css('height', h + 'px')
  3041.                     .fadeTo('normal',1);
  3042.             })();
  3043.         }
  3044.  
  3045.         if( forceOverFilter !== true ) {
  3046.             if( self._options.autoScroll ) {
  3047.                 jQuery('html,body').stop().animate({
  3048.                     scrollTop: self._jqContent.offset().top + self._options.addPixelsFromTop
  3049.                 }, 'low', function(){
  3050.                     self._busy = false;
  3051.                     self.render();
  3052.                 });
  3053.             } else {
  3054.                 self._busy = false;
  3055.                 self.render();
  3056.             }
  3057.         }
  3058.     },
  3059.  
  3060.     /**
  3061.      * Hide loader
  3062.      */
  3063.     _hideLoader: function() {
  3064.         var self = this;
  3065.  
  3066.         if( self._jqLoader !== null ) {
  3067.             self._jqLoader.remove();
  3068.             self._jqLoader = null;
  3069.         }
  3070.  
  3071.         if( self._jqLoaderFilter !== null ) {
  3072.             self._jqLoaderFilter.remove();
  3073.             self._jqLoaderFilter = null;
  3074.         }
  3075.     },
  3076.  
  3077.     /**
  3078.      * Render data
  3079.      */
  3080.     render: function( history ) {
  3081.         var self = this;
  3082.  
  3083.         if( self._lastResponse === '' || self._busy ) {
  3084.             return;
  3085.         }
  3086.  
  3087.         self._hideLoader();
  3088.  
  3089.         // remove all links to scripts JS
  3090.         self._lastResponse = self._lastResponse.replace( /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '' );
  3091.  
  3092.         var tmp = jQuery('<tmp>').html( self._lastResponse ),
  3093.             content = tmp.find(self._contentId), // find main container
  3094.             json = tmp.find('#mfilter-json'); // information JSON containing data on the number of products by category
  3095.  
  3096.         if( ! content.length && self._contentId != '#content' ) {
  3097.             content = tmp.find('#content');
  3098.         }
  3099.  
  3100.         if( content.length ) {
  3101.             var styles = self._jqContent.html().match( /<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi );
  3102.  
  3103.             if( styles != null && styles.length ) {
  3104.                 for( var i = 0; i < styles.length; i++ ) {
  3105.                     jQuery('head:first').append( styles[i] );
  3106.                 }
  3107.             }
  3108.  
  3109.             self._render( content.html(), json && json.length ? self.base64_decode(json.html()) : null, history );
  3110.  
  3111.             self._lastResponse = '';
  3112.         } else {
  3113.             self.reload();
  3114.         }
  3115.     },
  3116.  
  3117.     _render: function( html, json, history ) {
  3118.         var self = this;
  3119.  
  3120.         if( history !== true ) {
  3121.             self._lastUrl = self.createUrl();
  3122.  
  3123.             if( self._ajaxPagination !== null ) {
  3124.                 self._lastUrl += self._lastUrl.indexOf( '?' ) > -1 ? '&' : '?';
  3125.                 self._lastUrl += 'page=' + self._ajaxPagination;
  3126.  
  3127.                 self._ajaxPagination = null;
  3128.             }
  3129.  
  3130.             self._urlToFilters = null;
  3131.  
  3132.             if( self._options.seo.enabled ) {
  3133.                 var u = self.parse_url( self._lastUrl );
  3134.                 var data = jQuery.parseJSON( json );
  3135.  
  3136.                 self._lastUrl = '';
  3137.                 self._lastUrl += u.scheme + '://';
  3138.                 self._lastUrl += u.host;
  3139.                 self._lastUrl += typeof u.path != 'undefined' ? self.removeMfpFromUrl( decodeURIComponent( u.path ) ) : '/';
  3140.  
  3141.                 if( typeof data['url_alias'] != 'undefined' ) {
  3142.                     self._seoAliases[self.filtersToUrl( undefined, true )] = data['url_alias'];
  3143.                 }
  3144.  
  3145.                 if( typeof u.query != 'undefined' && u.query ) {
  3146.                     //if( u.path != '/' ) {
  3147.                         var mfp = u.query.match( /mfp=([^&]+)/ );
  3148.  
  3149.                         self._lastUrl = self._lastUrl.replace( /\/$/, '' );
  3150.  
  3151.                         if( mfp ) {
  3152.                             self._lastUrl += typeof data['url_alias'] == 'undefined' ? '/mfp/' + mfp[1] : '/' + data['url_alias'];
  3153.                             u.query = u.query.replace( 'mfp=' + mfp[1], '' );
  3154.                             u.query = u.query.replace( /^(\?|&)|&$/g, '' )
  3155.                             u.query = u.query.replace( /&&/g, '&' );
  3156.                         }
  3157.  
  3158.                         if( u.query != '' ) {
  3159.                             self._lastUrl += '?' + u.query;
  3160.                         }
  3161.  
  3162.                     //} else {
  3163.                     //  self._lastUrl += '?' + u.query;
  3164.                     //}
  3165.                 } else if( typeof data['url_alias'] != 'undefined' ) {
  3166.                     self._lastUrl += '/' + data['url_alias'];
  3167.                 }
  3168.             }
  3169.  
  3170.             try {
  3171.                 window.history.pushState({
  3172.                     'html'  : html,
  3173.                     'json'  : json,
  3174.                     'url'   : self._lastUrl
  3175.                 }, '', self._lastUrl );
  3176.  
  3177.                 self._history++;
  3178.             } catch( e ) {}
  3179.         }
  3180.  
  3181.         if( json ) {
  3182.             self.eachInstances(function( self ){
  3183.                 self._parseInfo( json );
  3184.             });
  3185.         }
  3186.  
  3187.         self.beforeRender( self._lastResponse, html, json );
  3188.  
  3189.         self._jqContent.html( html );
  3190.  
  3191.         /*if( self._box.hasClass( 'mfilter-content_top' ) ) {
  3192.             self._jqContent.prepend( self._box.removeClass('init') );
  3193.             self.init( self._box, self._options );
  3194.         }*/
  3195.  
  3196.         if( typeof jQuery.totalStorage == 'function' && jQuery.totalStorage('display') ) {
  3197.             display_MFP( jQuery.totalStorage('display') );
  3198.         } else if( typeof jQuery.cookie == 'function' && jQuery.cookie('display') ) {
  3199.             display_MFP( jQuery.cookie('display') );
  3200.         } else {
  3201.             display_MFP( 'list' );
  3202.         }
  3203.  
  3204.         for( var i in self ) {
  3205.             if( i.indexOf( '_initAlways' ) === 0 && typeof self[i] == 'function' ) {
  3206.                 self[i]();
  3207.             }
  3208.         }
  3209.  
  3210.         for( var f = 0; f < self._liveFilters.length; f++ ) {
  3211.             self._liveFilters[f].check();
  3212.         }
  3213.  
  3214.         // Support for Product Quantity Extension (15186)
  3215.         if( typeof pq_initExt == 'function' ) {
  3216.             pq_initExt();
  3217.         }
  3218.  
  3219.         if( self._options.routeHome == self._options.route && self._options.homePageAJAX ) {
  3220.             self._jqContent.find('.pagination > li > a').unbind('click').bind('click', function(){
  3221.                 self.ajax( jQuery(this).attr('href') );
  3222.  
  3223.                 return false;
  3224.             });
  3225.         }
  3226.  
  3227.         if( self._relativeScroll ) {
  3228.             self._relativeScroll.reinit();
  3229.         }
  3230.  
  3231.         self.afterRender( self._lastResponse, html, json );
  3232.     },
  3233.  
  3234.     beforeRequest: function(){},
  3235.  
  3236.     beforeRender: function(){},
  3237.  
  3238.     afterRender: function(){},
  3239.  
  3240.     eachInstances: function( fn, skipCurrent ) {
  3241.         for( var i = 0; i < MegaFilterINSTANCES.length; i++ ) {
  3242.             if( skipCurrent === true && i == this._instanceIdx ) continue;
  3243.  
  3244.             fn( MegaFilterINSTANCES[i] );
  3245.         }
  3246.     },
  3247.  
  3248.     /**
  3249.      * Load datas
  3250.      */
  3251.     ajax: function( url, history ) {
  3252.         var self = this;
  3253.  
  3254.         if( self._busy ) {
  3255.             self._waitingChanges = true;
  3256.  
  3257.             return;
  3258.         }
  3259.  
  3260.         (function(){
  3261.             var filters = self.filters( true );
  3262.  
  3263.             self.eachInstances(function( self ){
  3264.                 var params = $.extend( self.filters(), filters );
  3265.  
  3266.                 if( typeof filters.path == 'undefined' ) {
  3267.                     params.path = [self._path()];
  3268.                 }
  3269.  
  3270.                 self.setFiltersByUrl( params );
  3271.             }, true);
  3272.         })();
  3273.  
  3274.         if( typeof url == 'undefined' || url === null ) {
  3275.             url = [ self._options.routeProduct, self._options.routeHome, self._options.routeInformation, self._options.routeManufacturerList ].indexOf( self._options.route ) > -1 ? self.createUrl( self._options.ajaxResultsUrl, undefined, undefined, true ) : self.createUrl( undefined, undefined, undefined, true );
  3276.         } else {
  3277.             var mfpUrl = this.filtersToUrl();
  3278.  
  3279.             url = this.removeMfpFromUrl( url );
  3280.  
  3281.             if( mfpUrl != '' ) {
  3282.                 url += ( url.indexOf( '?' ) >= 0 ? '&' : '?' ) + 'mfp=' + mfpUrl;
  3283.             }
  3284.         }
  3285.  
  3286.         var cname   = url + self._options.idx;
  3287.  
  3288.         if( ( ! self._options.homePageAJAX && self._options.routeHome == self._options.route ) || [ self._options.routeProduct, self._options.routeInformation, self._options.routeManufacturerList ].indexOf( self._options.route ) > -1 ) {
  3289.             if( url.indexOf( 'path,' ) < 0 && url.indexOf( 'path[' ) < 0 && self._options.data.category_id !== null ) {
  3290.                 if( url.indexOf( 'mfp=' ) < 0 ) {
  3291.                     url += url.indexOf( '?' ) >= 0 ? '&' : '?';
  3292.                     url += 'mfp=';
  3293.                 } else {
  3294.                     url += ',';
  3295.                 }
  3296.                 url += 'force-path[' + self._options.data.category_id + ']';
  3297.             }
  3298.             window.location.href = url;return;
  3299.         }
  3300.  
  3301.         self.eachInstances(function( self ){
  3302.             self._busy = true;
  3303.             self._lastResponse = '';
  3304.         });
  3305.  
  3306.         self.renderSelectedFilters();
  3307.  
  3308.         self._showLoader();
  3309.  
  3310.         if( typeof self._params['page'] != 'undefined' ) {
  3311.             delete self._params['page'];
  3312.         }
  3313.  
  3314.         if( typeof self._cache.lastResponse[cname] != 'undefined' ) {
  3315.             self.eachInstances(function( self2 ){
  3316.                 self2._lastResponse = self._cache.lastResponse[cname];
  3317.             });
  3318.  
  3319.             setTimeout(function(){
  3320.                 self.eachInstances(function( self ){
  3321.                     self._busy = false;
  3322.                 });
  3323.  
  3324.                 self.render( history );
  3325.             }, 100);
  3326.  
  3327.             return;
  3328.         }
  3329.  
  3330.         if( self.beforeRequest() === false ) {
  3331.             return;
  3332.         }
  3333.  
  3334.         self._changed = true;
  3335.  
  3336.         jQuery.ajax({
  3337.             'type'      : 'GET',
  3338.             'url'       : self._ajaxUrl( url ),
  3339.             'timeout'   : 60 * 1000,
  3340.             'cache'     : false,
  3341.             'data'      : {
  3342.                 'mfilterAjax'   : '1',
  3343.                 'mfilterIdx'    : self._options.idx,
  3344.                 'mfilterBTypes' : self.baseTypes().join(','),
  3345.                 'mfilterPath'   : self._path(),
  3346.                 'mfilterLPath'  : self.locationPath()
  3347.             },
  3348.             'success'   : function( response ) {
  3349.                 self.eachInstances(function( self ){
  3350.                     self._busy = false;
  3351.                 });
  3352.  
  3353.                 if( response ) {
  3354.                     self.eachInstances(function( self ){
  3355.                         self._lastResponse  = response;
  3356.                         self._cache.lastResponse[cname] = response;
  3357.                     });
  3358.  
  3359.                     self.render( history );
  3360.  
  3361.                     if( self._waitingChanges ) {
  3362.                         self._waitingChanges = false;
  3363.                         self.ajax();
  3364.                     }
  3365.                 } else {
  3366.                     self.reload();
  3367.                 }
  3368.             },
  3369.             'error'     : function() {
  3370.                 self.reload();
  3371.             }
  3372.         });
  3373.     },
  3374.  
  3375.     /**
  3376.      * Create full URL
  3377.      */
  3378.     createUrl: function( url, attribs, force, ajax ) {
  3379.         var self    = this,
  3380.             params  = self.paramsToUrl( url, attribs ),
  3381.             filters = self.filtersToUrl( undefined, ajax ),
  3382.             urlSep  = self._urlSep;
  3383.  
  3384.         if( typeof url == 'undefined' ) {
  3385.             url = self._url;
  3386.         } else {
  3387.             urlSep = self._parseSep( url.split('#')[0] ).urlSep;
  3388.             url = self._parseSep( url.split('#')[0] ).url;
  3389.         }
  3390.  
  3391.         url = self.removeMfpFromUrl( decodeURIComponent( url ) );
  3392.  
  3393.         if( params || filters ) {
  3394.             url += urlSep.f;
  3395.  
  3396.             if( params ) {
  3397.                 url += params;
  3398.             }
  3399.  
  3400.             if( filters ) {
  3401.                 if( params ) {
  3402.                     url += urlSep.n;
  3403.                 }
  3404.  
  3405.                 url += 'mfp' + ( urlSep.n == '&' ? '=' : urlSep.n ) + filters;
  3406.             } else if( force ) {
  3407.                 var mfp = self.filtersToUrl( self.urlToFilters() );
  3408.  
  3409.                 if( mfp ) {
  3410.                     url += urlSep.n;
  3411.                     url += 'mfp' + ( urlSep.n == '&' ? '=' : urlSep.n ) + mfp;
  3412.                 }
  3413.             }
  3414.         }
  3415.  
  3416.         return url;
  3417.     },
  3418.  
  3419.     /**
  3420.      * Check correct entered price range
  3421.      *
  3422.      * @return bool
  3423.      */
  3424.     _validPrice: function( min, max ) {
  3425.         var self = this;
  3426.  
  3427.         min = parseInt( min );
  3428.         max = parseInt( max );
  3429.  
  3430.         if( min < self._options.priceMin )
  3431.             return false;
  3432.  
  3433.         if( max > self._options.priceMax )
  3434.             return false;
  3435.  
  3436.         if( min > max )
  3437.             return false;
  3438.  
  3439.         if( min == max && min == self._options.priceMin && max == self._options.priceMax )
  3440.             return false;
  3441.  
  3442.         return true;
  3443.     },
  3444.  
  3445.     /**
  3446.      * Make parameters from the URL to object
  3447.      *
  3448.      * @return object
  3449.      */
  3450.     urlToFilters: function( force ) {
  3451.         if( this._urlToFilters !== null ) {
  3452.             return this._urlToFilters;
  3453.         }
  3454.  
  3455.         var self = this;
  3456.  
  3457.         self._urlToFilters = {};
  3458.  
  3459.         if( ! self._params.mfp )
  3460.             return self._urlToFilters;
  3461.  
  3462.         self._params.mfp =  decodeURIComponent( self._params.mfp );
  3463.  
  3464.         self._urlToFilters = self.__urlToFilters( self._params.mfp );
  3465.  
  3466.         return self._urlToFilters;
  3467.     },
  3468.  
  3469.     __urlToFilters: function( mfp ) {
  3470.         var self    = this,
  3471.             obj     = {},
  3472.             matches = mfp.match( /[a-z0-9\-_]+\[[^\]]+\]/g );
  3473.  
  3474.         function validValue( key, val ) {
  3475.             switch( key ) {
  3476.                 case 'force-path' : {
  3477.                     self._options.data.force_category_id = val[0];
  3478.  
  3479.                     return null;
  3480.                 }
  3481.                 case 'price' : {
  3482.                     if( typeof val[0] != 'undefined' && val[1] != 'undefined' ) {
  3483.                         if( self._validPrice( val[0], val[1] ) )
  3484.                             return val;
  3485.                     }
  3486.  
  3487.                     return null;
  3488.                 }
  3489.                 case 'stock_status' : {
  3490.                     if( ! val.length || val[0] == '0' ) {
  3491.                         return [];
  3492.                     }
  3493.  
  3494.                     return val;
  3495.                 }
  3496.                 default : {
  3497.                     return val;
  3498.                 }
  3499.             }
  3500.         }
  3501.  
  3502.         if( ! matches ) {
  3503.             if( self._options.seo.enabled ) {
  3504.                 matches = mfp.split('/');
  3505.  
  3506.                 for( var i = 0; i < matches.length; i++ ) {
  3507.                     var val = matches[i].split(','),
  3508.                         key = val.shift();
  3509.  
  3510.                     val = validValue( key, val );
  3511.  
  3512.                     if( val !== null ) {
  3513.                         obj[key] = val;
  3514.                     }
  3515.                 }
  3516.             }
  3517.  
  3518.             return obj;
  3519.         }
  3520.  
  3521.         for( var i = 0; i < matches.length; i++ ) {
  3522.             var key = matches[i].match( /([a-z0-9\-_]+)\[[^\]]+\]/ )[1],
  3523.                 val = validValue( key, matches[i].match( /[a-z0-9\-_]+\[([^\]]+)\]/ )[1].split(',') );
  3524.  
  3525.             if( val !== null ) {
  3526.                 obj[key] = val;
  3527.             }
  3528.         }
  3529.  
  3530.         return obj;
  3531.     },
  3532.  
  3533.     resetFilters: function(){
  3534.         var self    = this;
  3535.  
  3536.         self._urlToFilters = null;
  3537.  
  3538.         if( self._params !== null ) {
  3539.             delete self._params.mfp;
  3540.         } else {
  3541.             self._params = {};
  3542.         }
  3543.  
  3544.         self._box.find('li[data-type]').each(function(){
  3545.             var _this       = jQuery(this),
  3546.                 type        = _this.attr('data-type'),
  3547.                 baseType    = _this.attr('data-base-type'),
  3548.                 defaultVal  = null;
  3549.  
  3550.             _this.find('.mfilter-input-active').removeClass('mfilter-input-active');
  3551.  
  3552.             if( baseType == 'stock_status' && self._options.inStockDefaultSelected ) {
  3553.                 defaultVal = self._options.inStockStatus;
  3554.             }
  3555.  
  3556.             switch( type ) {
  3557.                 case 'image_radio' :
  3558.                 case 'image' : {
  3559.                     _this.find('input[type=checkbox]:checked,input[type=radio]:checked').prop('checked', false).parent().removeClass('mfilter-image-checked');
  3560.  
  3561.                     break;
  3562.                 }
  3563.                 case 'cat_checkbox' : {
  3564.                     _this.find('input[type=checkbox]:checked').prop('checked', false);
  3565.                     _this.find('.mfilter-counter').removeClass('mfilter-close');
  3566.  
  3567.                     break;
  3568.                 }
  3569.                 case 'tree' : {
  3570.                     _this.find('input[name=path]').val( typeof self._options.params.path_aliases == 'undefined' ? ( typeof self._options.params.path == 'undefined' ? '' : self._options.params.path ) : self._options.params.path_aliases );
  3571.  
  3572.                     break;
  3573.                 }
  3574.                 case 'rating' :
  3575.                 case 'stock_status' :
  3576.                 case 'manufacturers' :
  3577.                 case 'discounts' :
  3578.                 case 'checkbox' :
  3579.                 case 'image_list_checkbox' :
  3580.                 case 'image_list_radio' :
  3581.                 case 'radio' : {
  3582.                     _this.find('input[type=checkbox]:checked,input[type=radio]:checked').prop('checked', false);
  3583.                     _this.find('.mfilter-counter').removeClass('mfilter-close');
  3584.  
  3585.                     if( defaultVal !== null ) {
  3586.                         _this.find('input[value="' + defaultVal.replace( /"/g, '&quot;' ) + '"]').prop('checked', true)
  3587.                             .parent().parent().find('.mfilter-counter').addClass('mfilter-close');
  3588.                     }
  3589.  
  3590.                     break;
  3591.                 }
  3592.                 case 'search_oc' :
  3593.                 case 'search' : {
  3594.                     _this.find('input[id="mfilter-opts-search"]').val( '' );
  3595.  
  3596.                     break;
  3597.                 }
  3598.                 case 'text' : {
  3599.                     _this.find('input[type=text]').val( '' );
  3600.  
  3601.                     break;
  3602.                 }
  3603.                 case 'slider' : {
  3604.  
  3605.  
  3606.                     break;
  3607.                 }
  3608.                 case 'price' : {
  3609.                     _this.find('input[id="mfilter-opts-price-min"]').val( self._options.priceMin );
  3610.                     _this.find('input[id="mfilter-opts-price-max"]').val( self._options.priceMax );
  3611.                     _this.find('[id="mfilter-price-slider"]').each(function(){
  3612.                         jQuery(this).slider( 'option', 'min', self._options.priceMin );
  3613.                         jQuery(this).slider( 'option', 'max', self._options.priceMax );
  3614.                         jQuery(this).slider( 'option', 'values', [ self._options.priceMin, self._options.priceMax ] );
  3615.                         jQuery(this).slider( 'value', jQuery(this).slider('value') );
  3616.                     });
  3617.  
  3618.                     break;
  3619.                 }
  3620.                 case 'levels' :
  3621.                 case 'vehicles' :
  3622.                 case 'related' :
  3623.                 case 'select' : {
  3624.                     _this.find('select option').removeAttr('selected');
  3625.  
  3626.                     if( defaultVal !== null ) {
  3627.                         _this.find('select option').each(function(i){
  3628.                             if( jQuery(this).val() == defaultVal ) {
  3629.                                 jQuery(this).attr('selected', true);
  3630.                                 _this.find('select').prop('selectedIndex', i);
  3631.  
  3632.                                 return false;
  3633.                             }
  3634.                         });
  3635.                     } else {
  3636.                         _this.find('select option:first').attr('selected', true);
  3637.                         _this.find('select').prop('selectedIndex', 0);
  3638.                     }
  3639.  
  3640.                     if( type == 'related' ) {
  3641.                         _this.find('select').each(function(i){
  3642.                             if( i ) {
  3643.                                 if( _this.attr('data-auto-levels') ) {
  3644.                                     jQuery(this).parent().remove();
  3645.                                 } else {
  3646.                                     jQuery(this).find('option[value!=""]').remove();
  3647.                                 }
  3648.                             }
  3649.                         });
  3650.                     }
  3651.  
  3652.                     _this.find('select.mf_selectpicker').mf_selectpicker('refresh');
  3653.  
  3654.                     break;
  3655.                 }
  3656.             }
  3657.         });
  3658.  
  3659.         for( var i = 0; i < self._sliders.length; i++ ) {
  3660.             self._sliders[i].resetValues();
  3661.         }
  3662.  
  3663.         self.renderSelectedFilters();
  3664.     },
  3665.  
  3666.     /**
  3667.      * Get current values of all filters
  3668.      *
  3669.      * @return object
  3670.      */
  3671.     filters: function( alsoEmpty, ajax ) {
  3672.         var self    = this,
  3673.             params  = { },
  3674.             stockStatusExist = self._box.find('li[data-base-type="stock_status"]').length ? true : false;
  3675.  
  3676.         if( typeof self._options.data.force_category_id != 'undefined' ) {
  3677.             params['path'] = [ self._options.data.force_category_id ];
  3678.         }
  3679.  
  3680.         self._box.find('li[data-type]').each(function(){
  3681.             var _this   = jQuery(this),
  3682.                 type    = _this.attr('data-type'),
  3683.                 seoName = _this.attr('data-seo-name');
  3684.  
  3685.             if( alsoEmpty === true ) {
  3686.                 if( typeof params[seoName] == 'undefined' ) {
  3687.                     params[seoName] = [];
  3688.                 }
  3689.             }
  3690.  
  3691.             switch( type ) {
  3692.                 case 'cat_checkbox' :
  3693.                 case 'rating' :
  3694.                 case 'stock_status' :
  3695.                 case 'manufacturers' :
  3696.                 case 'discounts' :
  3697.                 case 'image_list_checkbox' :
  3698.                 case 'image' :
  3699.                 case 'checkbox' : {
  3700.                     _this.find('input[type=checkbox]:checked').each(function(){
  3701.                         if( typeof params[seoName] == 'undefined' ) {
  3702.                             params[seoName] = [];
  3703.  
  3704.                             /*if( type == 'cat_checkbox' ) {
  3705.                                 if( typeof self._options.params.mfp_org_path != 'undefined' ) {
  3706.                                     params[seoName].push( self._options.params.mfp_org_path );
  3707.                                 } else if( typeof self._options.params.path != 'undefined' ) {
  3708.                                     params[seoName].push( self._options.params.path );
  3709.                                 }
  3710.                             }*/
  3711.                         }
  3712.  
  3713.                         params[seoName].push( encodeURIComponent( self.encode( jQuery(this).val() ) ) );
  3714.                     });
  3715.  
  3716.                     break;
  3717.                 }
  3718.                 case 'image_radio' :
  3719.                 case 'image_list_radio' :
  3720.                 case 'radio' : {
  3721.                     _this.find('input[type=radio]:checked').each(function(){
  3722.                         params[seoName] = [ encodeURIComponent( self.encode( jQuery(this).val() ) ) ];
  3723.                     });
  3724.  
  3725.                     break;
  3726.                 }
  3727.                 case 'slider' : {
  3728.                     var slider_id = _this.attr('data-slider-id'),
  3729.                         slider_vals = self._sliders[slider_id].getValues();
  3730.  
  3731.                     if( slider_vals.length ) {
  3732.                         params[seoName] = slider_vals;
  3733.                     }
  3734.  
  3735.                     break;
  3736.                 }
  3737.                 case 'price' : {
  3738.                     var priceRange = self.getPriceRange();
  3739.  
  3740.                     if( priceRange.min != self._options.priceMin || priceRange.max != self._options.priceMax ) {
  3741.                         if( self._validPrice( priceRange.min, priceRange.max ) )
  3742.                             params[seoName] = [ priceRange.min, priceRange.max ];
  3743.                     }
  3744.  
  3745.                     break;
  3746.                 }
  3747.                 case 'search_oc' :
  3748.                 case 'search' : {
  3749.                     _this.find('input[id="mfilter-opts-search"]').each(function(){
  3750.                         if( jQuery(this).val() !== '' ) {
  3751.                             params[seoName] = [ encodeURIComponent( self.encode( jQuery(this).val() ) ) ];
  3752.                         }
  3753.                     });
  3754.  
  3755.                     break;
  3756.                 }
  3757.                 case 'text' : {
  3758.                     _this.find('input[type=text]').each(function(){
  3759.                         if( jQuery(this).val() != '' ) {
  3760.                             params[seoName] = [ encodeURIComponent( self.encode( jQuery(this).val() ) ) ];
  3761.                         }
  3762.                     });
  3763.  
  3764.                     break;
  3765.                 }
  3766.                 case 'select' : {
  3767.                     _this.find('select').each(function(){
  3768.                         if( jQuery(this).val() )
  3769.                             params[seoName] = [ encodeURIComponent( self.encode( jQuery(this).val() ) ) ];
  3770.                     });
  3771.  
  3772.                     break;
  3773.                 }
  3774.                 case 'levels' :
  3775.                 case 'vehicles' :
  3776.                 case 'related' : {
  3777.                     //if( _this.find('select:last').val() ) {
  3778.                         _this.find('select').each(function(){
  3779.                             var val = jQuery(this).val();
  3780.  
  3781.                             if( val ) {
  3782.                                 if( typeof params[seoName] == 'undefined' )
  3783.                                     params[seoName] = [];
  3784.  
  3785.                                 params[seoName].push( val );
  3786.                             }
  3787.                         });
  3788.                     //}
  3789.                 }
  3790.                 case 'tree' : {
  3791.                     _this.find('input').each(function(){
  3792.                         var val = jQuery(this).val();
  3793.  
  3794.                         if( val ) {
  3795.                             params['path'] = [ val ];
  3796.                         }
  3797.                     });
  3798.  
  3799.                     break;
  3800.                 }
  3801.             }
  3802.         });
  3803.  
  3804.         // check that the default should be selected "in stock"
  3805.         if( self._options.inStockDefaultSelected && typeof params['stock_status'] == 'undefined' ) {
  3806.             params['stock_status'] = stockStatusExist ? [ 0 ] : [ self._options.inStockStatus ];
  3807.         }
  3808.  
  3809.         if( ! ajax && typeof params.path != 'undefined' ) {
  3810.             if( typeof self._seoAliases[self.filtersToUrl(params)] != 'undefined' && params.path == self._path() ) {
  3811.                 delete params['path'];
  3812.             } else if( typeof self._options.params.path_aliases != 'undefined' && params.path == self._options.params.path_aliases ) {
  3813.                 delete params['path'];
  3814.             } else if( typeof self._options.params.path != 'undefined' && params.path == self._options.params.path ) {
  3815.                 delete params['path'];
  3816.             }
  3817.         }
  3818.  
  3819.         return params;
  3820.     },
  3821.  
  3822.     /**
  3823.      * Create a URL based on parameters
  3824.      */
  3825.     filtersToUrl: function( params, ajax ) {
  3826.         var self    = this,
  3827.             url     = '';
  3828.  
  3829.         if( typeof params == 'undefined' ) {
  3830.             params  = self.filters( false, ajax );
  3831.  
  3832.             self.eachInstances(function( self ){
  3833.                 params = $.extend( self.filters( false, ajax ), params );
  3834.             }, true);
  3835.         }
  3836.  
  3837.         if( ! ajax && self._options.seo.enabled ) {
  3838.             for( var i in params ) {
  3839.                 url += url ? '/' : '';
  3840.                 url += '' + i + ',' + params[i].join(',');
  3841.             }
  3842.         } else {
  3843.             for( var i in params ) {
  3844.                 url += url ? ',' : '';
  3845.                 url += '' + i + '[' + params[i].join(',') + ']';
  3846.             }
  3847.         }
  3848.  
  3849.         return url;
  3850.     },
  3851.  
  3852.     /**
  3853.      * Make parameters to the URL
  3854.      *
  3855.      * @return string
  3856.      */
  3857.     paramsToUrl: function( url, attribs ) {
  3858.         var self    = this,
  3859.             params  = typeof url == 'undefined' ? self._params : self._parseUrl( url, attribs ),
  3860.             urlSep  = typeof url == 'undefined' ? self._urlSep : self._parseSep( url ).urlSep;
  3861.  
  3862.         return self._paramsToUrl( params, {
  3863.             'skip'  : [ 'mfilter-ajax', 'mfp', 'page' ],
  3864.             'sep'   : urlSep.n,
  3865.             'sep2'  : urlSep.n == '&' ? '=' : urlSep.n,
  3866.             'fn'    : function( i ) {
  3867.                 return typeof url == 'undefined' && typeof self._inUrl[i] == 'undefined';
  3868.             }
  3869.         });
  3870.     },
  3871.  
  3872.     _paramsToUrl: function( params, o ) {
  3873.         var url = '';
  3874.  
  3875.         o = jQuery.extend({
  3876.             'skip'  : [],
  3877.             'sep'   : '&',
  3878.             'sep2'  : '=',
  3879.             'fn'    : function(){}
  3880.         }, typeof o == 'object' ? o : {});
  3881.  
  3882.         for( var i in params ) {
  3883.             if( o.skip.indexOf( i ) > -1 ) continue;
  3884.  
  3885.             if( o.fn( i, params[i] ) ) continue;
  3886.  
  3887.             url += url ? o.sep : '';
  3888.             url += i + o.sep2 + params[i];
  3889.         }
  3890.  
  3891.         return url;
  3892.     },
  3893.  
  3894.     /**
  3895.      * @param url string
  3896.      * @param attribs object
  3897.      * @return object
  3898.      */
  3899.     _parseUrl: function( url, attribs ) {
  3900.         if( typeof attribs != 'object' )
  3901.             attribs = {
  3902.                 'mfilter-ajax'  : '1'
  3903.             };
  3904.  
  3905.         if( typeof url == 'undefined' )
  3906.             return attribs;
  3907.  
  3908.         var self    = this,
  3909.             params, i, name, value, param,
  3910.             mfp;
  3911.  
  3912.         url = url.split('#')[0];
  3913.         mfp = url.match( /\/mfp,([a-z0-9\-_]+\[[^\]]*\],?)+/g );
  3914.  
  3915.         if( mfp ) {
  3916.             attribs['mfp'] = mfp[0].split('?')[0].replace( /^\/mfp,/, '' );
  3917.         } else {
  3918.             mfp = url.match( /\/mfp\/([a-z0-9\-_]+,[^\/]+\/?)+/g );
  3919.  
  3920.             if( mfp ) {
  3921.                 attribs['mfp'] = mfp[0].split('?')[0].replace( /^\/mfp\//, '' );
  3922.             }
  3923.         }
  3924.  
  3925.         if( url.indexOf( '?' ) > -1 || url.indexOf( '&' ) > -1 ) {
  3926.             params = typeof self.parse_url( url ).query != 'undefined' ? self.parse_url( url ).query.split('&') : url.split('&');
  3927.  
  3928.             for( i = 0; i < params.length; i++ ) {
  3929.                 if( params[i].indexOf( '=' ) < 0 ) continue;
  3930.  
  3931.                 param   = params[i].split('=');
  3932.                 name    = param[0];
  3933.                 value   = param[1];
  3934.  
  3935.                 if( ! name ) continue;
  3936.  
  3937.                 attribs[name] = value;
  3938.             }
  3939.         } else {
  3940.             params  = url.split( ';' );
  3941.             name    = null;
  3942.  
  3943.             for( i = 1; i < params.length; i++ ) {
  3944.                 if( name === null )
  3945.                     name = params[i];
  3946.                 else {
  3947.                     attribs[name] = params[i];
  3948.                     name = null;
  3949.                 }
  3950.             }
  3951.         }
  3952.  
  3953.         return attribs;
  3954.     },
  3955.  
  3956.     /**
  3957.      * Reload page
  3958.      */
  3959.     reload: function() {
  3960.         var self = this;
  3961.  
  3962.         window.location.href = self.createUrl();
  3963.     }
  3964. };
  3965. var MegaFilterLang = {};
  3966.  
  3967. function display_MFP(view) {
  3968.     // Product List
  3969.     $('#list-view').click(function() {
  3970.         $('#content .product-grid > .clearfix').remove();
  3971.  
  3972.         $('#content .row > .product-grid').attr('class', 'product-layout product-list col-xs-12');
  3973.  
  3974.         localStorage.setItem('display', 'list');
  3975.     });
  3976.  
  3977.     // Product Grid
  3978.     $('#grid-view').click(function() {
  3979.         $('#content .product-layout > .clearfix').remove();
  3980.  
  3981.         // What a shame bootstrap does not take into account dynamically loaded columns
  3982.         var cols = $('#column-right, #column-left').length;
  3983.  
  3984.         if (cols == 2) {
  3985.             $('#content .product-list').attr('class', 'product-layout product-grid col-lg-6 col-md-6 col-sm-12 col-xs-12');
  3986.         } else if (cols == 1) {
  3987.             $('#content .product-list').attr('class', 'product-layout product-grid col-lg-4 col-md-4 col-sm-6 col-xs-12');
  3988.         } else {
  3989.             $('#content .product-list').attr('class', 'product-layout product-grid col-lg-3 col-md-3 col-sm-6 col-xs-12');
  3990.         }
  3991.  
  3992.         localStorage.setItem('display', 'grid');
  3993.     });
  3994.  
  3995.     if (localStorage.getItem('display') == 'list') {
  3996.         $('#list-view').trigger('click');
  3997.     } else {
  3998.         $('#grid-view').trigger('click');
  3999.     }
  4000. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement