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.
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:
0 1 2 3 4 5 6 7 8 |
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($('<span data-value="' + s[el].ValueId + '" class="button-option">' + s[el].Value + '</span>').data('el', JSON.stringify(s[el]))); } |
Kod znajdujący się w pętli for zamień na:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
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($('<span data-value="' + s[el].ValueId + '" class="button-option' + unavailableClassName + '">' + s[el].Value + '</span>').data('el', JSON.stringify(s[el]))); |
Następnie wyszukaj fragment:
0 1 2 3 4 5 6 7 8 |
function SetSupl(drop, s) { var form = drop.closest('#AddToCartForm'); var fDrop = form.find('.attributes-select'); drop.empty(); for (var el in s) { drop.append($('<span data-value="' + s[el].ValueId + '" class="button-option">' + s[el].Value + '</span>').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:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
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:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
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:
0 1 2 |
drop.append($('<span data-value="' + s[el].ValueId + '" class="button-option |
I dla wszystkich znalezionych przypadków, na końcu fragmentów takich jak przedstawiony powyżej, dodaj kod:
0 1 2 |
' + unavailableClassName + ' |
Na koniec zmian w pliku, odnajdź poniższe instrukcje:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
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:
0 1 2 |
drop.append($('<span data-value="' + s[el].ValueId + '" class="button-option |
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:
0 1 2 |
.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} |
0 1 2 |
.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:
0 1 2 |
.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}}} |
0 1 2 |
.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} |