Przekreślenie na atrybutach towaru zgrupowanego – szablon Topaz

Wstęp

W szablonie Topaz, przy włączonej kontroli stanów magazynowych, w przypadku braku produktu towaru zgrupowanego wyświetlany jest przycisk „Powiadom mnie o dostępności”. Z tego artykułu dowiesz się jak zmodyfikować swój szablon, aby dodatkowo wyświetlać przekreślenie na niedostępnych atrybutach.

Wskazówka
W tym artykule dowiesz się jak wprowadzać zmiany w plikach js i css. Z tego artykułu dowiesz się jak je minifikować.

Zmiany w plikach szablonu

Przedstawione w artykule modyfikacje są kompatybilne ze wszystkimi czterema widokami szczegółów towaru w szablonie Topaz. Kod odpowiedzialny za przekreślenie na atrybutach, będzie prawie identyczny dla każdego z widoków. Minimalne różnice zostały odpowiednio opisane.

Edycję szablonu rozpocznij od pliku js/layout2.js. Struktura części kodu, którą należy zmienić może się różnić, w zależności czy masz zaimplementowaną graficzną prezentację atrybutów. Dlatego przedstawione zostaną dwa przypadki edycji omawianego pliku.

W przypadku braku implementacji graficznej prezentacji atrybutów, odnajdź fragment:
function SetSuplFirst(drop, s, lvl, valId) {
var form = drop.parent().parent().parent();
var fDrop = form.find('.attributes-select');
drop.empty();
for (var el in s) {
drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el])));
}

Kod znajdujący się w pętli for zamień na:
var isUnavailable = false;
var unavailableClassName = "";
if (s[el].Product) {
if (s[el].Product.StockLevel && s[el].Product.StockLevel.Value === 0) {
isUnavailable = true;
}
if (s[el].StockLevel && s[el].StockLevel.Value === 0) {
isUnavailable = true;
}
}
else {
var checkStockLevelLoopObj = s[el];
var checkSuppliesStockLevelLoopObj = s[el];
while (typeof checkStockLevelLoopObj.Product === 'undefined') {
checkSuppliesStockLevelLoopObj = checkStockLevelLoopObj.Supplies;
checkStockLevelLoopObj = checkStockLevelLoopObj.Supplies[0];
}
if (checkSuppliesStockLevelLoopObj.length > 1) {
for (var supply in checkSuppliesStockLevelLoopObj) {
if (checkSuppliesStockLevelLoopObj[supply].Product && checkSuppliesStockLevelLoopObj[supply].Product.StockLevel
&& checkSuppliesStockLevelLoopObj[supply].Product.StockLevel !== 0) {
break;
}
else {
if (checkSuppliesStockLevelLoopObj[supply].Product && !checkSuppliesStockLevelLoopObj[supply].Product.StockLevel) {
break;
} else {
isUnavailable = true;
}
}
if (checkSuppliesStockLevelLoopObj[supply].StockLevel && checkSuppliesStockLevelLoopObj[supply].StockLevel.Value !== 0) {
break;
}
else {
if (!checkSuppliesStockLevelLoopObj[supply].StockLevel) {
break;
} else {
isUnavailable = true;
}
}
}
}
else {
if (checkStockLevelLoopObj.Product && checkStockLevelLoopObj.Product.StockLevel && checkStockLevelLoopObj.Product.StockLevel === 0) {
isUnavailable = true;
}
if (checkStockLevelLoopObj.StockLevel && checkStockLevelLoopObj.StockLevel.Value === 0) {
isUnavailable = true;
}
}
}
if (isUnavailable) {
unavailableClassName = " button-option-unavailable";
}
drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el])));

Następnie wyszukaj fragment:
function SetSupl(drop, s) {
var form = drop.closest('#AddToCartForm');
var fDrop = form.find('.attributes-select');
drop.empty();
for (var el in s) {
drop.append($('' + s[el].Value + '').data('el', JSON.stringify(s[el])));
}

I instrukcje w pętli for zastąp tym samym kodem co w przypadku przedstawionej wyżej modyfikacji funkcji SetSuplFirst.

Dla przypadku zaimplementowanej graficznej prezentacji atrybutów, zlokalizuj fragment:
function SetSuplFirst(drop, s, lvl, valId) {
var form = drop.parent().parent().parent();
var fDrop = form.find('.attributes-select'); //pobieram wszystkie kontenery dla poziomów
drop.empty();
var attributesColorsData = drop.data('variants-colors');
var pageLanguage = drop.data('page-language');
var attributesColors = [];
if (attributesColorsData) {
attributesColorsData = attributesColorsData.split('|||');
for (var i = 0; i < attributesColorsData.length; i++) {
var attributesColor = attributesColorsData[i].split('||');
var attributeColorName = attributesColor[0].split('|');
switch (pageLanguage) {
case 1:
attributeColorName = attributeColorName[0];
break;
case 2:
attributeColorName = attributeColorName[1];
break;
case 3:
attributeColorName = attributeColorName[2];
break;
case 5:
attributeColorName = attributeColorName[3];
break;
default:
break;
}
attributesColors.push([attributeColorName,attributesColor[1]]);
}
}
for (var el in s) {
if (drop.data('variants-colors')) {
if ((drop.data('colors-option') === 'Grouping_First' && drop.data('attribute-id') === drop.data('first-attribute-id'))
|| (drop.data('colors-option') === 'Grouping_Last' && drop.data('attribute-id') === drop.data('last-attribute-id'))
|| (drop.data('colors-option') === 'Grouping_All')) {

Teraz w pętli for (var el in s), przed pierwszą instrukcją sterującą if wklej:
var isUnavailable = false;
var unavailableClassName = "";
if (s[el].Product) {
if (s[el].Product.StockLevel && s[el].Product.StockLevel.Value === 0) {
isUnavailable = true;
}
if (s[el].StockLevel && s[el].StockLevel.Value === 0) {
isUnavailable = true;
}
}
else {
var checkStockLevelLoopObj = s[el];
var checkSuppliesStockLevelLoopObj = s[el];
while (typeof checkStockLevelLoopObj.Product === 'undefined') {
checkSuppliesStockLevelLoopObj = checkStockLevelLoopObj.Supplies;
checkStockLevelLoopObj = checkStockLevelLoopObj.Supplies[0];
}
if (checkSuppliesStockLevelLoopObj.length > 1) {
for (var supply in checkSuppliesStockLevelLoopObj) {
if (checkSuppliesStockLevelLoopObj[supply].Product && checkSuppliesStockLevelLoopObj[supply].Product.StockLevel
&& checkSuppliesStockLevelLoopObj[supply].Product.StockLevel !== 0) {
break;
}
else {
if (checkSuppliesStockLevelLoopObj[supply].Product && !checkSuppliesStockLevelLoopObj[supply].Product.StockLevel) {
break;
} else {
isUnavailable = true;
}
}
if (checkSuppliesStockLevelLoopObj[supply].StockLevel && checkSuppliesStockLevelLoopObj[supply].StockLevel.Value !== 0) {
break;
}
else {
if (!checkSuppliesStockLevelLoopObj[supply].StockLevel) {
break;
} else {
isUnavailable = true;
}
}
}
}
else {
if (checkStockLevelLoopObj.Product && checkStockLevelLoopObj.Product.StockLevel && checkStockLevelLoopObj.Product.StockLevel === 0) {
isUnavailable = true;
}
if (checkStockLevelLoopObj.StockLevel && checkStockLevelLoopObj.StockLevel.Value === 0) {
isUnavailable = true;
}
}
}
if (isUnavailable) {
unavailableClassName = " button-option-unavailable";
}

Następnie, w obrębie wspomnianej wyżej pętli for, wyszukaj wszystkie wystąpienia kodu zawierające fragment:
drop.append($('
I dla wszystkich znalezionych przypadków, na końcu fragmentów takich jak przedstawiony powyżej, dodaj kod:
' + unavailableClassName + '

Na koniec zmian w pliku, odnajdź poniższe instrukcje:
function SetSupl(drop, s) {
var form = drop.closest('#AddToCartForm');
var fDrop = form.find('.attributes-select'); //pobieram wszystkie kontenery dla poziomów
drop.empty();
var attributesColorsData = drop.data('variants-colors');
var pageLanguage = drop.data('page-language');
var attributesColors = [];
if (attributesColorsData) {
attributesColorsData = attributesColorsData.split('|||');
for (var i = 0; i < attributesColorsData.length; i++) {
var attributesColor = attributesColorsData[i].split('||');
var attributeColorName = attributesColor[0].split('|');
switch (pageLanguage) {
case 1:
attributeColorName = attributeColorName[0];
break;
case 2:
attributeColorName = attributeColorName[1];
break;
case 3:
attributeColorName = attributeColorName[2];
break;
case 5:
attributeColorName = attributeColorName[3];
break;
default:
attributeColorName = attributeColorName[0];
break;
}
attributesColors.push([attributeColorName,attributesColor[1]]);
}
}
for (var el in s) {
if (drop.data('variants-colors')) {
if ((drop.data('colors-option') === 'Grouping_First' && drop.data('attribute-id') === drop.data('first-attribute-id'))
|| (drop.data('colors-option') === 'Grouping_Last' && drop.data('attribute-id') === drop.data('last-attribute-id'))
|| (drop.data('colors-option') === 'Grouping_All')) {

Teraz dokonaj analogicznych modyfikacji jak w obrębie funkcji SetSuplFirst. Pamiętaj, że tym razem, zmiany we wszystkich wystąpieniach kodu:
drop.append($('
Musisz dokonać w obrębie funkcji SetSupl.

Do dokończenia zmian w szablonie pozostało zmodyfikowanie pliku ze stylami. W zależności od wygenerowanego w kreatorze szablonu widoku szczegółów towaru, nazwa edytowanego pliku będzie się różnić. Zmiany stylistyki w szablonie są identyczne dla wszystkich widoków, lecz umieszczane w innych fragmentach plików.

Najpierw przedstawiona zostanie modyfikacja przeznaczona dla pierwszego i drugiego widoku szczegółów towaru. Otwórz plik css/layout0.css i wyszukaj fragment:
.product-details .input-group input[type='button'].active,.product-details .input-group .attributes-select .button-option.active,.product-details .set .button-option.active,.product-details .set .button-option-sets.active{border:2px solid {{settings.paginationActiveBorderColor}};background-color:transparent}

Teraz tuż za ostatnim znakiem przedstawionego kodu wklej instrukcje:
.product-details .button-option-unavailable{position:relative;color:{{settings.secondaryFontColor}};transition:300ms}.product-details .button-option-unavailable::before{content:"";position:absolute;top:0;left:0;height:100%;width:100%;transition:300ms;background-color:rgba(226,226,226,0.2)}.product-details .button-option-unavailable::after{content:"";display:block;position:absolute;top:0;left:0;height:100%;width:100%;transition:300ms;cursor:pointer}@keyframes change-gradient-to-inactive{from{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 52%, transparent)}to{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent)}}@keyframes change-gradient-to-active{from{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent)}to{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 52%, transparent)}}.product-details .button-option-unavailable:not(.active){border:1px solid {{settings.secondaryFontColor}} !important}.product-details .button-option-unavailable:not(.active)::after{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent);-webkit-animation:change-gradient-to-inactive 300ms;animation:change-gradient-to-inactive 300ms}.product-details .button-option-unavailable.active{border:2px solid {{settings.secondaryFontColor}} !important}.product-details .button-option-unavailable.active::after{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 52%, transparent);-webkit-animation:change-gradient-to-active 900ms;animation:change-gradient-to-active 900ms}

Poniżej natomiast pokazane są zmiany przeznaczone dla trzeciego i czwartego widoku szczegółów towaru. Otwórz plik css/layout0.css i wyszukaj fragment:
.productDetails-attributes .button-option:not(.dropdown):not(.units-container){display:flex;flex-direction:row;justify-content:flex-start;align-items:center;margin-bottom:10px;flex-wrap:wrap}.productDetails-attributes .button-option:not(.dropdown):not(.units-container).active{border:2px solid {{settings.linkFontColor}};display:inline-flex}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) span{height:50px;padding-left:15px;padding-right:15px;font-size:14px;font-weight:normal;font-stretch:normal;font-style:normal;line-height:1.71;letter-spacing:1.2px;text-align:center;color:{{settings.primaryFontColor}};border:2px solid {{settings.primaryPageBgColor}};cursor:pointer;transition:300ms;margin-right:5px}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) span:not(.active):hover{border-color:{{settings.secondaryFontColor}}}

Następnie zaraz po ostatnim znaku powyższego fragmentu dodaj kod:
.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable{position:relative;color:{{settings.secondaryFontColor}};transition:300ms}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable::before{content:"";position:absolute;top:0;left:0;height:100%;width:100%;transition:300ms;background-color:rgba(226,226,226,0.2)}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable::after{content:"";display:block;position:absolute;top:0;left:0;height:100%;width:100%;transition:300ms;cursor:pointer}@keyframes change-gradient-to-inactive{from{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.linkFontColor}} 50%, {{settings.linkFontColor}} 50%, transparent 52%, transparent)}to{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent)}}@keyframes change-gradient-to-active{from{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent)}to{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.linkFontColor}} 50%, {{settings.linkFontColor}} 50%, transparent 52%, transparent)}}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable:not(.active){border:1px solid {{settings.secondaryFontColor}}}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable:not(.active)::after{background:linear-gradient(to right top, transparent, transparent 49%, {{settings.secondaryFontColor}} 50%, {{settings.secondaryFontColor}} 50%, transparent 51%, transparent);-webkit-animation:change-gradient-to-inactive 300ms;animation:change-gradient-to-inactive 300ms}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable.active{border:1px solid {{settings.linkFontColor}}}.productDetails-attributes .button-option:not(.dropdown):not(.units-container) .button-option-unavailable.active::after{background:linear-gradient(to right top, transparent, transparent 48%, {{settings.linkFontColor}} 50%, {{settings.linkFontColor}} 50%, transparent 52%, transparent);-webkit-animation:change-gradient-to-active 900ms;animation:change-gradient-to-active 900ms}

Czy ten artykuł był pomocny?