1(function ($, _) { 2 var TemPlazaProductsFilterWidget = function () { 3 var self = this; 4 5 self.ajax = null; 6 7 // Init. 8 self.init(); 9 10 // Methods. 11 self.init = self.init.bind(self); 12 self.initDropdowns = self.initDropdowns.bind(self); 13 self.removeSliderInputs = self.removeSliderInputs.bind(self); 14 self.sendAjaxRequest = self.sendAjaxRequest.bind(self); 15 16 // Events. 17 $('.products-filter-widget') 18 .on('input', '.products-filter__search-box', {widget: self}, self.searchTerms) 19 .on('click', '.products-filter--collapsible .products-filter__option-toggler', {widget: self}, self.toggleCollapse) 20 .on('click', '.products-filter__option-name, .products-filter__options .swatch', {widget: self}, self.toggleItem) 21 .on('change', 'input, select', {widget: self}, self.triggerItemChange) 22 .on('click', '.reset-button', {widget: self}, self.resetFilters) 23 .on('click', '.clear-button', {widget: self}, self.clearFilters) 24 .on('click', '.remove-filtered', {widget: self}, self.removeFiltered) 25 .on('submit', 'form.ajax-filter', {widget: self}, self.ajaxSearch); 26 27 $(document.body) 28 .on('price_slider_create', self.addListenerToSlider) 29 .on('templaza_products_filter_change', {widget: self}, self.instantSearch) 30 .on('templaza_products_filter_request_success', self.updateURL) 31 .on('templaza_products_filter_request_success', {widget: self}, self.updateForm) 32 .on('templaza_products_filter_widget_updated', {widget: self}, self.initDropdowns) 33 .on('templaza_products_filter_widget_updated', {widget: self}, self.initSliders); 34 }; 35 36 TemPlazaProductsFilterWidget.prototype.init = function () { 37 var self = this; 38 39 self.initDropdowns(); 40 self.removeSliderInputs(); 41 } 42 43 TemPlazaProductsFilterWidget.prototype.initDropdowns = function (event, form) { 44 if (!$.fn.select2) { 45 return; 46 } 47 48 var $container = form ? $(form) : $('.products-filter-widget'), 49 direction = $(document.body).hasClass('rtl') ? 'rtl' : 'ltr'; 50 51 $('select', $container).each(function () { 52 var $select = $(this), 53 $searchBoxText = $select.prev('.products-filter__search-box'), 54 searchText = $searchBoxText.length ? $searchBoxText.text() : false; 55 $select.select2({ 56 dir: direction, 57 width: '100%', 58 minimumResultsForSearch: searchText ? 3 : -1, 59 dropdownCssClass: 'products-filter-dropdown', 60 dropdownParent: $select.parent() 61 }); 62 }); 63 } 64 65 TemPlazaProductsFilterWidget.prototype.initSliders = function (event, form) { 66 $(document.body).trigger('init_price_filter'); 67 68 event.data.widget.removeSliderInputs(form); 69 } 70 71 TemPlazaProductsFilterWidget.prototype.removeSliderInputs = function (form) { 72 var $container = form ? $(form) : $('.products-filter-widget'); 73 74 $('.widget_price_filter', $container).find('input[type=hidden]').not('[name=min_price], [name=max_price]').remove(); 75 } 76 77 TemPlazaProductsFilterWidget.prototype.searchTerms = function (event) { 78 var $this = $(this), 79 term = $this.children().val().toLowerCase(), 80 $list = $this.next('.products-filter__options').find('.products-filter__option'); 81 82 if (term) { 83 $list.hide().filter(function () { 84 return $('.name', this).text().toLowerCase().indexOf(term) !== -1; 85 }).show(); 86 } else { 87 $list.show(); 88 } 89 } 90 91 TemPlazaProductsFilterWidget.prototype.toggleCollapse = function (event) { 92 var $option = $(this).closest('.products-filter__option'), 93 $children = $option.children('ul'); 94 95 if (!$children.length) { 96 return; 97 } 98 99 event.preventDefault(); 100 101 $children.stop(true, true).slideToggle(function () { 102 $option.toggleClass('active'); 103 }); 104 } 105 106 TemPlazaProductsFilterWidget.prototype.toggleItem = function (event) { 107 event.preventDefault(); 108 109 var $item = $(this).closest('.products-filter__option'), 110 $filter = $item.closest('.filter'), 111 $input = $item.closest('.templaza_woo_filter-control').find('input[type=hidden]'), 112 current = $input.val(), 113 value = $item.data('value'), 114 form = $item.closest('form').get(0), 115 index = -1; 116 117 if ($filter.hasClass('multiple')) { 118 current = current ? current.split(',') : []; 119 index = current.indexOf(value); 120 index = (-1 !== index) ? index : current.indexOf(value.toString()); 121 122 if (index !== -1) { 123 current = _.without(current, value); 124 } else { 125 current.push(value); 126 } 127 128 $input.val(current.join(',')); 129 $item.toggleClass('selected'); 130 131 $input.prop('disabled', current.length <= 0); 132 133 if ($filter.hasClass('attribute')) {
134 var $queryTypeInput = $input.next('input[name^=query_type_]'); 135 136 if ($queryTypeInput.length) { 137 $queryTypeInput.prop('disabled', current.length <= 1); 138 } 139 } 140 } else { 141 // @note: Ranges are always single selection. 142 if ($item.hasClass('selected')) { 143 $item.removeClass('selected'); 144 $input.val('').prop('disabled', true); 145 146 if ($filter.hasClass('ranges')) { 147 $input.next('input[type=hidden]').val('').prop('disabled', true); 148 } 149 } else { 150 $item.addClass('selected').siblings('.selected').removeClass('selected'); 151 $input.val(value).prop('disabled', false); 152 153 if ($filter.hasClass('ranges')) { 154 $input.val(value.min).prop('disabled', !value.min); 155 $input.next('input[type=hidden]').val(value.max).prop('disabled', !value.max); 156 } 157 } 158 } 159 160 $(document.body).trigger('templaza_products_filter_change', [form]); 161 } 162 163 TemPlazaProductsFilterWidget.prototype.triggerItemChange = function () { 164 var form = $(this).closest('form').get(0); 165 $(document.body).trigger('templaza_products_filter_change', [form]); 166 } 167 168 TemPlazaProductsFilterWidget.prototype.addListenerToSlider = function () { 169 var $slider = $('.products-filter-widget .price_slider.ui-slider'); 170 171 $slider.each(function () { 172 var $el = $(this), 173 form = $el.closest('form').get(0), 174 onChange = $el.slider('option', 'change'); 175 176 $el.slider('option', 'change', function (event, ui) { 177 onChange(event, ui); 178 179 $(document.body).trigger('templaza_products_filter_change', [form]); 180 }); 181 }); 182 } 183 184 TemPlazaProductsFilterWidget.prototype.resetFilters = function () { 185 var $form = $(this).closest('form'); 186 187 $form.get(0).reset(); 188 $form.find('.selected').removeClass('selected'); 189 $form.find(':input').not('[type="button"], [type="submit"], [type="reset"]') 190 .val('') 191 .trigger('change') 192 .filter('[type="hidden"],[name="min_price"], [name="max_price"]').prop('disabled', true); 193 194 $form.trigger('submit'); 195 $(document.body).trigger('templaza_products_filter_reseted'); 196 } 197 198 TemPlazaProductsFilterWidget.prototype.clearFilters = function () { 199 var $filter = $(this).closest('.templaza_woo_filter'), 200 $form = $(this).closest('form'); 201 202 $filter.find('.selected').removeClass('selected'); 203 $filter.find(':input').not('[type="button"], [type="submit"], [type="reset"]') 204 .val('') 205 .trigger('change') 206 .filter('[type="hidden"]').prop('disabled', true); 207 $form.trigger('submit'); 208 $(document.body).trigger('templaza_products_filter_cleared'); 209 } 210 211 TemPlazaProductsFilterWidget.prototype.removeFiltered = function (event) { 212 event.preventDefault(); 213 214 var self = event.data.widget, 215 $el = $(this), 216 $widget = $el.closest(' .products-filter-widget'), 217 $form = $widget.find('form'), 218 name = $el.data('name'), 219 key = name.replace(/^filter_/g, ''), 220 value = $el.data('value'), 221 $filter = $widget.find('.filter.' + key); 222 223 $el.remove(); 224 225 if ($filter.length) { 226 var $input = $filter.find(':input[name=' + name + ']'), 227 current = $input.val(); 228 229 if( name == 'price' ) { 230 $filter.find(':input[name=min_price]').val(''); 231 $filter.find(':input[name=max_price]').val(''); 232 $filter.find('.products-filter__option').removeClass('selected'); 233 } else { 234 if ($input.is('select')) { 235 $input.prop('selectedIndex', 0); 236 $input.trigger('change'); 237 } else { 238 current = current.replace(',' + value, ''); 239 current = current.replace(value, ''); 240 $input.val(current); 241 242 if ('' == current) { 243 $input.prop('disabled', true); 244 } 245 246 $filter.find('[data-value=' + value + ']').removeClass('selected'); 247 } 248 } 249 250 251 252 self.sendAjaxRequest($form); 253 } 254 } 255 256 TemPlazaProductsFilterWidget.prototype.ajaxSearch = function (event) { 257 event.data.widget.sendAjaxRequest(this); 258 259 return false;
260 } 261 262 TemPlazaProductsFilterWidget.prototype.instantSearch = function (event, form) { 263 var settings = $(form).data('settings'); 264 265 if (!settings.instant) { 266 return; 267 } 268 269 event.data.widget.sendAjaxRequest(form); 270 } 271 272 TemPlazaProductsFilterWidget.prototype.updateURL = function (event, response, url, form) { 273 var settings = $(form).data('settings'); 274 275 if (!settings.change_url) { 276 return; 277 } 278 279 if ('?' === url.slice(-1)) { 280 url = url.slice(0, -1); 281 } 282 283 url = url.replace(/%2C/g, ','); 284 285 history.pushState(null, '', url); 286 } 287 288 TemPlazaProductsFilterWidget.prototype.updateForm = function (event, response, url, form) { 289 var $widget = $(form).closest('.widget.products-filter-widget'), 290 widgetId = $widget.attr('id'), 291 $newWidget = $('#' + widgetId, response); 292 293 if (!$newWidget.length) { 294 return; 295 } 296 297 $('.filters', form).html($('.filters', $newWidget).html()); 298 $('.products-filter__activated', $widget).html($('.products-filter__activated', $newWidget).html()); 299 300 $(document.body).trigger('templaza_products_filter_widget_updated', [form]); 301 } 302 303 TemPlazaProductsFilterWidget.prototype.sendAjaxRequest = function (form) { 304 var self = this, 305 $form = $(form), 306 $container = $('#templaza-shop-container .products'), 307 $inputs = $form.find(':input:not(:checkbox):not(:button)'), 308 params = {}, 309 action = $form.attr('action'), 310 separator = action.indexOf('?') !== -1 ? '&' : '?', 311 url = action; 312 313 params = $inputs.filter(function () { 314 return this.value != '' && this.name != ''; 315 }).serializeObject(); 316 317 if (params.min_price && params.min_price == $inputs.filter('[name=min_price]').data('min')) { 318 delete params.min_price; 319 } 320 321 if (params.max_price && params.max_price == $inputs.filter('[name=max_price]').data('max')) { 322 delete params.max_price; 323 } 324 325 // the filer always contains "filter" param 326 // so it is empty if the size less than 2 327 if (_.size(params) > 1) { 328 url += separator + $.param(params, true); 329 } 330 331 if (!$container.length) { 332 $container = $('<ul class="products"/>'); 333 $('#templaza-shop-container .woocommerce-info').replaceWith($container); 334 } 335 336 if (self.ajax) { 337 self.ajax.abort(); 338 } 339 340 $form.addClass('filtering'); 341 $container.addClass('loading').append('<li class="templaza-posts__loading"><span class="templaza-loading"></span> </li>'); 342 343 $(document.body).trigger('templaza_products_filter_before_send_request', $container); 344 345 self.ajax = $.get(url, function (response) { 346 var $html = $(response), 347 $products = $html.find('#templaza-shop-container .products'), 348 $pagination = $container.closest('.templaza-shop-container').find('.woocommerce-pagination'); 349 350 if (!$products.length) { 351 $products = $html.find('#main .woocommerce-info'); 352 $pagination.fadeOut(); 353 354 $container.replaceWith($products); 355 } else { 356 var $nav = $products.closest('.templaza-shop-container').find('.woocommerce-pagination'), 357 $order = $('form.woocommerce-ordering'); 358 359 if ($nav.length) { 360 if ($pagination.length) { 361 $pagination.replaceWith($nav).fadeIn(); 362 } else { 363 $container.after($nav); 364 } 365 } else { 366 $pagination.fadeOut(); 367 } 368 369 $products.children().each(function (index, product) { 370 $(product).css('animation-delay', index * 100 + 'ms'); 371 }); 372 373 // Modify the ordering form. 374 $inputs.each(function () { 375 var $input = $(this), 376 name = $input.attr('name'), 377 value = $input.val(); 378 379 if (name === 'orderby') { 380 return; 381 } 382 383 if ('min_price' === name && value == $input.data('min')) { 384 $order.find('input[name="min_price"]').remove(); 385 return; 386 } 387 388 if ('max_price' === name && value == $input.data('max')) { 389 $order.find('input[name="max_price"]').remove(); 390 return; 391 } 392 393 $order.find('input[name="' + name + '"]').remove(); 394 395 if (value !== '' && value != 0) { 396 $('<input type="hidden" name="' + name + '">').val(value).appendTo($order); 397 } 398 }); 399 400 $container.replaceWith($products); 401 $products.find('li.product').addClass('animated templazaFadeInUp'); 402 403 $(document.body).trigger('templaza_products_loaded', [$products.children(), false]); // appended = false 404 } 405 406 $form.removeClass('filtering'); 407 $(document.body).trigger('templaza_products_filter_request_success', [response, url, form]); 408 }); 409 } 410 411 $(function () { 412 new TemPlazaProductsFilterWidget(); 413 }) 414})(jQuery, _);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.