Modyfikacja listy towarów w Topazie – filtrowanie bez przeładowania strony

Od wersji 2021.2 w szablonie Topaz zmodyfikowane zostały listy produktów. Dotychczas filtrując poszczególne towary, należało nacisnąć przycisk „filtruj” co przeładowywało stronę i wyświetlało przefiltrowane produkty. Obecnie filtrowanie odbywa się w sposób dynamiczny, bez odświeżania strony. Lista towarów aktualizuje się od razu po wybraniu odpowiedniego filtra. Niniejsza instrukcja objaśnia, w jaki sposób zmodyfikować szablon Topaz, by osiągnąć opisywany efekt.

Artykuł podzielony będzie na trzy sekcje.

  • Pierwsza dotyczy modyfikacji we wspólnych częściach dla obu wariantów listy towarów.
  • Druga dotyczy wyłącznie pierwszego widoku listy towarów (w plikach szablonu: elements/products-list/products-1.html)
  • Trzecia sekcja dotyczy wyłącznie drugiego widoku (w tym samym katalogu plik products-2.html)

Modyfikacje dla obu wersji listy towarów

1. Plik base_layout.html

Otwórz plik base_layout.html w głównym katalogu z plikami szablonu. Wyszukaj linię __translations = {. Pod nią znajdują się wymienione tłumaczenia, które trafiają do funkcji js. Do ostatniego na tej liście dopisz przecinek na końcu, i pod spodem wklej:

NotifyAboutAvailability: "{{translations.NotifyAboutAvailability}}",
Com_LogInToSeePrice: "{{translations.Com_LogInToSeePrice}}",
Com_AskForPrice: "{{translations.Com_AskForPrice}}",
Com_From: "{{ translations.Com_From }}"

Nad wyszukaną wcześniej linią __translations = {, wklej poniższy kod:

__isEnterprise = '{{config.ENTERPRISE}}'; __hidePrices = '{{customer.HidePrices}}';

2. Plik product-item.html

Otwórz plik partials/product-item.html. Wyszukaj w nim linię:

<code lang=”ruby”>

</code>

Przed aria-label, a po otwarciu tagu a, dopisz class=”product-url” .

Modyfikacje dla pierwszego wariantu

Modyfikacja HTML

Otwieramy plik elements/products-list/products-1.html.
a) Wyszukujemy linię rozpoczynającą się od:. Usuwamy w tej linii następujący fragment kodu: {% if value.Count == 0 -%} disabled {% endif -%}
To samo wykonujemy kilka linii poniżej, w linii zaczynającej się od .

b) Wyszukujemy linię z elementem div, posiadającym klasę primary-action-button. Na liście jego klas dodajemy klasę hidden.

c) Wyszukujemy linię {% if anythingSelected -%} Kasujemy ją i odpowiadającą jej linię {% endif -%} (kilkanaście linii niżej, tuż nad {% assign productsItems = products.Products -%}.

d) Wyszukujemy div’a o id reset-filters. Na jego liście klas musimy dodać warunek {% if anythingSelected == false -%} hidden {% endif -%}

e) Wyszukujemy div’a z klasą removeFilter-js. Są dwa div’y o tej klasie. Nam chodzi o div’a znajdującego się w warunku {% if fo.PriceFrom != null and fo.PriceTo != null -%}. Na liście klas tego div’a dodajemy sliderPriceFilter.

f) Wyszukujemy linię {% if minProductNo < 1 -%}. Tuż nad nią znajduje się element span. Przerabiamy go w następujący sposób:
.

g) Wyszukujemy linię {% if valuesSize > 4 -%}. W kodzie są dwie takie linie, bierzemy pierwszą – nad nią znajduje się {% assign valuesSize = filter.Values | Size -%}. Usuwamy tę znalezioną linię i kilka kolejnych, kod do usunięcia wygląda tak:

{% if valuesSize > 4 -%}
{% assign redundantValues = filter.Values | Skip:4 -%}
{% assign visibleValues = filter.Values | Take:4 -%}
{% else -%}
{% assign visibleValues = filter.Values -%}
{% endif -%}

h) Tuż pod usuniętym kodem znajduje się tag li z klasą filter-group-wrapper. Musimy usunąć go całego, a w jego miejsce wkleić poniższy kod:

            • {{ filter.Heading }}

        {% if counter > 4 and counter == filterSize -%}

        {% endif -%}
        {% assign counter = counter | Plus: 1 -%}
        {% endfor -%}

        {% if filterSize > 3 -%}
        {{ translations.Com_More }}
        {{ translations.Com_Less }}
        {% endif -%}

 

Modyfikacja JS

Otwórz plik js/layout1.js. Wyszukaj linię kodu o treści var productListFunctions = {. Zaznacz cały blok kodu, począwszy od tej linii po klamrę zamykającą (pojedyncza klamra, nad którą 3 linie powyżej znajduje się $(’body’).on(’mouseleave’, ’.product-item’, function() {). Usuń ten blok kodu a w jego miejsce wklej następujący:

var ajax_lock = false;
var productListFunctions = {
init: function () {
productListFunctions.events();
productListFunctions.applyResetFilters();
productListFunctions.setPriceSlider();
if(localStorage.getItem('productListType') != null){
productListFunctions.changeListView();
}
productListFunctions.removeEmptyFilters();
$('.redundant').slideToggle();
},
applyResetFilters: function() {
$.pushObj = function (t, o) { var p; for (p in o) t.push({ name: p, value: o[p] }); }
$(„.product-list__filters .filter-group-wrapper .filter-group .redundant”).each(function(i, element) {
// check if in hidden filter values (redundant) are checked ones
// if yes they should be displayed
if ($(element).children().children().children().children(„input[checked]”).length) {
$(element).toggle();
$(element.parentNode).children(„.filter-more”).toggle();
$(element.parentNode).children(„.filter-less”).toggle();
}
});$(„.product-list__filters .filter-group-wrapper .filter-group input[checked]”).each(function(i, element) {
$(element).parent().addClass(’custom-checkbox–checked’);
});
},
resetFilters: function() {
$($(’.searchFilters-js’).find(’input:checked’).prop(’checked’, false));
$(’.productsList__priceSlider__minPrice-js’).val($(’.productsList__priceSlider__minPrice-js’).attr(’min’));
$(’.productsList__priceSlider__from-js’).text($(’.productsList__priceSlider__minPrice-js’).attr(’min’));
$(’.productsList__priceSlider__maxPrice-js’).val($(’.productsList__priceSlider__maxPrice-js’).attr(’max’));
$(’.productsList__priceSlider__to-js’).text($(’.productsList__priceSlider__maxPrice-js’).attr(’max’));
productListFunctions.setPriceSlider();
$(’.getSearchFilters-js’).click();
},
removeFilter: function (e) {
var filterId = $(e.currentTarget).data(’filter-id’);if (filterId === 'price’) {
$(’.productsList__priceSlider__minPrice-js’).val($(’.productsList__priceSlider__minPrice-js’).attr(’min’));
$(’.productsList__priceSlider__from-js’).text($(’.productsList__priceSlider__minPrice-js’).attr(’min’));
$(’.productsList__priceSlider__maxPrice-js’).val($(’.productsList__priceSlider__maxPrice-js’).attr(’max’));
$(’.productsList__priceSlider__to-js’).text($(’.productsList__priceSlider__maxPrice-js’).attr(’max’));
productListFunctions.setPriceSlider();
$(’.getSearchFilters-js’).click();
} else {
$($(’.searchFilters-js’).find(’input:checked[value=”’ + filterId + '”]’)[0]).prop(„checked”, false);
$(’.getSearchFilters-js’).click();
}
},
reloadFilters: function () {
productListFunctions.refreshPagination();
var filters;
var countSelected = 0;
var isSelected = [];
$.get(”, {__collection: 'products.FilteringOptions.Filters’}, function(data) { filters = data.collection; }).done(function() {
for(f in filters) {
isSelected[f] = false;
for(val in filters[f].Values) {
if(filters[f].Values[val].Selected) {
isSelected[f] = true;
}
}
if(isSelected[f] == true) {
countSelected++;
}
}$(’.filter-group’).each(function() {
if($(this).find(’label’)) {
var sum;
for(f in filters) {
sum = 0;
if($(this).find(’label’).attr(’for’).toLowerCase().includes(filters[f].Field.toLowerCase())) {
var labels = $(this).find(’.filter-label’);
labels.each(function(label) {
if(countSelected == 1 && isSelected[f] == true) {
labels.eq(label).text(filters[f].Values[label].Text + ’ (’ + filters[f].Values[label].TotalCount + ’)’);
} else {
labels.eq(label).text(filters[f].Values[label].Text + ’ (’ + filters[f].Values[label].Count + ’)’);
}
});

}
}
}
});
$(’.removeFilter-js’).remove();
var minPrice = $(’.productsList__priceSlider__minPrice-js’);
var maxPrice = $(’.productsList__priceSlider__maxPrice-js’);

if(minPrice.val() !== minPrice.attr(’min’) || maxPrice.val() !== maxPrice.attr(’max’)) {
$(’.selectedFilters-js’).append(’


+ minPrice.val() + ’ – ’ + maxPrice.val() + ’ ’ + __curr
+ ’

’);
}

for(f in filters) {
for(val in filters[f].Values) {
if(filters[f].Values[val].Selected == true) {
$(’.selectedFilters-js’).append(’


+ filters[f].Values[val].Text + ’

’);
}
}
}

if($(’.removeFilter-js’).length > 0) {
$(’#reset-filters’).removeClass(’hidden’);
} else {
$(’#reset-filters’).addClass(’hidden’);
}
});
setTimeout(function() {
productListFunctions.removeEmptyFilters();
},1000);
},
removeEmptyFilters:function() {
$(’.filter-group’).each(function() {
var label = $(this).find(’.filter-label’);

label.each(function() {
var number = $(this).text().substring(
$(this).text().lastIndexOf(„(„)+1,
$(this).text().lastIndexOf(„)”)
);
var filterInput = $(this).parent().parent().find(’.filter-input’);
if(number == 0 && filterInput.prop(’checked’) == false) {
filterInput.attr(’disabled’, 'disabled’);
} else {
filterInput.removeAttr(’disabled’);
}
});
});
},
refreshPagination: function() {
var URLstring = window.location.origin + window.location.pathname
$.get(”, {__collection: 'products’}, function(result) {
var pagination = result.collection;
var pageCount = pagination.PageCount;
var totalItems = pagination.TotalItems;
var selectedSorting = pagination.SelectedSorting;
if(pageCount > 1) {
if($(’.product-list__grid-wrapper’).children(’.product-list__pagination’).length < 1) {
$(’.product-list__grid-wrapper’).append(’

’);
$(’.product-list__pagination’).append(’

’);
} else {
$(’.product-list__pagination > *’).remove();
$(’.product-list__pagination’).append(’

’);
}
$(’.pagination’).append(’

 

            • {{ filter.Heading }}

          {% assign filterSize = filter.Values | Size | Minus: 1 -%}
          {% assign counter = 0 -%}

          {% for value in filter.Values -%}
          {% if counter == 4 -%}

          {% endif -%}

        • {% if counter > 4 and counter == filterSize -%}

          {% endif -%}
          {% assign counter = counter | Plus: 1 -%}
          {% endfor -%}

          {% if filterSize > 3 -%}
          {{ translations.Com_More }}
          {{ translations.Com_Less }}
          {% endif -%}

Czy ten artykuł był pomocny?