Skip to content

Commit 4f9b8ab

Browse files
committed
Keep accordions open and add language handling
Update accordion navigation and add improved language handling and UX fixes across productPage.js and luxuryCar.js. Key changes: - productPage.js: next-step navigation no longer closes the current step; it now calls openNextAccordion which opens and scrolls to the next panel (previous steps remain open). - productPage.js: simplified openNextAccordion to only add active class and scroll after animation. - luxuryCar.js: introduce project-aware language detection variables and use them to localize twentytwenty labels, FAQ show-more text, box/config labels and model info header (CS/SK support). - luxuryCar.js: consolidate and relocate openNextAccordion implementation and reuse it for multiple flows (button clicks, upsale behavior) to auto-open and scroll to relevant panels. - luxuryCar.js: enforce selection validation when navigating forward by clicking a future step, highlight missing selections briefly. - luxuryCar.js: minor bug fixes and robustness improvements: numeric equality fix (==), fallback for addPrice when absent, prevent config opening for 'none' buttons, ensure next-step button text switches for SK language, update upsale banner logic to auto-open trunk/boxs panels when appropriate, and correct setup language retrieval variable. Purpose: improve UX by keeping previous accordion steps visible while progressing, ensure consistent scrolling to newly opened sections, and provide correct Czech/Slovak translations and more robust handling of edge cases (price computation, button states, and step validation).
1 parent aa6b847 commit 4f9b8ab

File tree

2 files changed

+100
-50
lines changed

2 files changed

+100
-50
lines changed

assets/js/components/productPage.js

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -471,20 +471,14 @@ function priplatky(setupData, texts) {
471471
if (currentIndex < allWraps.length - 1) {
472472
const nextWrap = allWraps.eq(currentIndex + 1);
473473

474-
// Zavři současný element
475-
currentWrap.removeClass("active");
476-
477-
// Otevři následující element
478-
nextWrap.addClass("active");
474+
// Nechej současný krok otevřený, otevři a scrolluj na další
475+
openNextAccordion(nextWrap);
479476

480477
console.log("Přechod k dalšímu kroku:", nextWrap.find(".variant.name, h5").first().text() || "Unnamed");
481478
} else {
482479
console.log("Konfigurace dokončena");
483480
// Zavři všechny elementy
484481
allWraps.removeClass("active");
485-
486-
// Můžeme zde přidat další logiku pro dokončení konfigurace
487-
// například zvýraznění tlačítka "Přidat do košíku" nebo zobrazení shrnutí
488482
}
489483

490484
// Aktualizuj texty tlačítek po každé změně
@@ -684,16 +678,9 @@ function priplatky(setupData, texts) {
684678
}
685679
}
686680

687-
// Otevře akordeon, zachová max 2 otevřená okna (nejstarší zavře), scrolluje na nové
681+
// Otevře akordeon a scrolluje na něj — předchozí kroky zůstávají otevřené
688682
function openNextAccordion($next) {
689683
$next.addClass("active");
690-
const $allOpen = $(
691-
".content-wrap > .position-wrap.active, .content-wrap > .parameter-wrap.active, " +
692-
".upsale-buttons.trunk.active, .upsale-buttons.boxs.active"
693-
);
694-
if ($allOpen.length > 2) {
695-
$allOpen.first().removeClass("active");
696-
}
697684
// Čekáme na dokončení CSS animací předchozích akordeonů, pak teprve počítáme offset
698685
setTimeout(() => {
699686
$("html, body").animate({ scrollTop: $next.offset().top - 80 }, 400);

assets/js/luxuryCar.js

Lines changed: 97 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ var optionData = {
88

99
// assets/js/components/index.js
1010
function intIndex() {
11+
const lang2 = dataLayer[0].shoptet.projectId == 704436 ? "cs" : shoptetData.language || dataLayer[0].shoptet.language;
1112
setTimeout(function() {
1213
$(".twentytwenty-container").twentytwenty({
13-
before_label: "Potom",
14-
after_label: "P\u0159edt\xEDm"
14+
before_label: lang2 === "cs" ? "Potom" : "Po",
15+
after_label: lang2 === "cs" ? "P\u0159edt\xEDm" : "Predt\xFDm"
1516
});
1617
}, 1e3);
1718
$("svg.icon.icon-circle-button-right-clipped").remove();
@@ -436,19 +437,19 @@ function accordion() {
436437
}
437438
});
438439
if (!$(this).find(".faq-show-more").length) {
439-
const showMore = $(`<div class="faq-show-more"><button type="button">Zobrazit v\xEDce</button></div>`);
440+
const showMore = $(`<div class="faq-show-more"><button type="button">${lang === "sk" ? "Zobrazi\u0165 viac" : "Zobrazit v\xEDce"}</button></div>`);
440441
$(this).append(showMore);
441442
showMore.on("click", "button", function() {
442443
const hidden = $(this).closest(".faq").find(".accordion-hidden");
443444
if (hidden.length) {
444445
hidden.removeClass("accordion-hidden");
445-
$(this).text("Zobrazit m\xE9n\u011B");
446+
$(this).text(lang === "sk" ? "Zobrazi\u0165 menej" : "Zobrazit m\xE9n\u011B");
446447
} else {
447448
const $accordions2 = $(this).closest(".faq").find(".accordion-wrapper");
448449
$accordions2.each(function(i) {
449450
if (i >= 4) $(this).addClass("accordion-hidden");
450451
});
451-
$(this).text("Zobrazit v\xEDce");
452+
$(this).text(lang === "sk" ? "Zobrazi\u0165 viac" : "Zobrazit v\xEDce");
452453
$(this).closest(".faq").find(".panel").css("display", "none");
453454
$(this).closest(".faq").find(".accordion").removeClass("active");
454455
}
@@ -470,6 +471,7 @@ function accordion() {
470471
var twoLayersProducts;
471472
var boxsParameterIds2;
472473
var oneLayerProducts;
474+
var language = dataLayer[0].shoptet.projectId == 704436 ? "cs" : shoptetData.language || dataLayer[0].shoptet.language;
473475
if ($(".type-product")[0]) {
474476
twoLayersProducts = shoptetData.product.id == 601 || shoptetData.product.id == 604 || shoptetData.product.id == 607;
475477
boxsParameterIds2 = [94, 97, 104];
@@ -502,7 +504,7 @@ var ButtonUtils = {
502504
* @returns {string} CSS class for button type
503505
*/
504506
getButtonTypeClass: (type, value) => {
505-
if (type === "config" && value === 0) return "none";
507+
if (type === "config" && value == 0) return "none";
506508
if (value === "89-2225") return "radio none";
507509
return type;
508510
}
@@ -539,7 +541,7 @@ function createUpsaleButton(img, text, position, value, type, price2, prefix, te
539541
function createOptions(position, orders) {
540542
let name = "";
541543
if (position == "box") {
542-
name = "Po\u010Det boxov";
544+
name = language === "cs" ? "Po\u010Det box\u016F" : "Po\u010Det boxov";
543545
} else if (position == "sizes") {
544546
name = "ve\u013Ekos\u0165";
545547
} else {
@@ -707,11 +709,11 @@ function createBoxConfig() {
707709
}).appendTo(wrap);
708710
$("<div>", {
709711
class: "close-btn close bottom",
710-
text: "Nechci"
712+
text: language === "sk" ? "Nechcem" : "Nechci"
711713
}).appendTo(wrap);
712714
$("<div>", {
713715
class: "close-btn return",
714-
text: "potvrdit"
716+
text: language === "sk" ? "potvrdi\u0165" : "potvrdit"
715717
}).appendTo(wrap);
716718
const configWrap = $("<div>", {
717719
class: "config-wrap"
@@ -894,7 +896,7 @@ var boxy = 91;
894896
var box1 = 94;
895897
var box2 = 97;
896898
var boxsPrice = [];
897-
var language = shoptetData.language;
899+
var language2 = dataLayer[0].shoptet.projectId == 704436 ? "cs" : shoptetData.language || dataLayer[0].shoptet.language;
898900
if (dataLayer[0].shoptet.projectId == "581408") {
899901
koberce = 60;
900902
boxy = 63;
@@ -1074,7 +1076,7 @@ function priplatky(setupData2, texts) {
10741076
}
10751077
const isLast = index === allWraps.length - 1;
10761078
let buttonText = isLast ? "Dokon\u010Dit konfiguraci" : "P\u0159ej\xEDt k dal\u0161\xEDmu kroku";
1077-
if (dataLayer[0].shoptet.language == "sk") {
1079+
if (language2 === "sk") {
10781080
buttonText = isLast ? "Dokon\u010Di\u0165 konfigur\xE1ciu" : "Prejs\u0165 k \u010Fal\u0161iemu kroku";
10791081
}
10801082
const buttonClass = isLast ? "next-step-button finish-button" : "next-step-button";
@@ -1093,7 +1095,10 @@ function priplatky(setupData2, texts) {
10931095
const isLast = index === allWraps.length - 1;
10941096
console.log(index);
10951097
console.log(isLast);
1096-
const buttonText = isLast ? "Dokon\u010Dit konfiguraci" : "P\u0159ej\xEDt k dal\u0161\xEDmu kroku";
1098+
let buttonText = isLast ? "Dokon\u010Dit konfiguraci" : "P\u0159ej\xEDt k dal\u0161\xEDmu kroku";
1099+
if (language2 === "sk") {
1100+
buttonText = isLast ? "Dokon\u010Di\u0165 konfigur\xE1ciu" : "Prejs\u0165 k \u010Fal\u0161iemu kroku";
1101+
}
10971102
$button.text(buttonText);
10981103
$button.toggleClass("finish-button", isLast);
10991104
}
@@ -1211,6 +1216,20 @@ function priplatky(setupData2, texts) {
12111216
clickedWrap.removeClass("active");
12121217
return;
12131218
}
1219+
const allWraps = $(".position-wrap, .parameter-wrap");
1220+
const clickedIndex = allWraps.index(clickedWrap);
1221+
const $activeWrap = $(".position-wrap.active, .parameter-wrap.active").first();
1222+
const activeIndex = $activeWrap.length ? allWraps.index($activeWrap) : -1;
1223+
if (clickedIndex > activeIndex && activeIndex >= 0) {
1224+
for (let i = 0; i < clickedIndex; i++) {
1225+
const $wrap = allWraps.eq(i);
1226+
if (!isWrapSelectionValid($wrap)) {
1227+
$wrap.addClass("selection-required");
1228+
setTimeout(() => $wrap.removeClass("selection-required"), 1200);
1229+
return;
1230+
}
1231+
}
1232+
}
12141233
$(".position-wrap, .parameter-wrap").removeClass("active");
12151234
clickedWrap.addClass("active");
12161235
const elementType = clickedWrap.hasClass("position-wrap") ? "position-wrap" : "parameter-wrap";
@@ -1231,8 +1250,7 @@ function priplatky(setupData2, texts) {
12311250
const currentIndex = allWraps.index(currentWrap);
12321251
if (currentIndex < allWraps.length - 1) {
12331252
const nextWrap = allWraps.eq(currentIndex + 1);
1234-
currentWrap.removeClass("active");
1235-
nextWrap.addClass("active");
1253+
openNextAccordion(nextWrap);
12361254
console.log("P\u0159echod k dal\u0161\xEDmu kroku:", nextWrap.find(".variant.name, h5").first().text() || "Unnamed");
12371255
} else {
12381256
console.log("Konfigurace dokon\u010Dena");
@@ -1343,10 +1361,28 @@ function priplatky(setupData2, texts) {
13431361
$(`.navigatte-button:eq(${optionName})`).addClass("active");
13441362
});
13451363
console.log("clickaaaa");
1364+
const contentStepCount = $(".content-wrap").children(".position-wrap, .parameter-wrap").length;
1365+
$(".upsale-buttons.trunk .order").text(contentStepCount);
1366+
$(".upsale-buttons.boxs .order").text(contentStepCount + 1);
13461367
}
13471368
}
1369+
function openNextAccordion($next) {
1370+
$next.addClass("active");
1371+
setTimeout(() => {
1372+
$("html, body").animate({ scrollTop: $next.offset().top - 80 }, 400);
1373+
}, 600);
1374+
}
13481375
$(document).on("click", ".upsale-button", function(e) {
13491376
updateUpsale(this, e);
1377+
const $trunk = $(this).closest(".upsale-buttons.trunk");
1378+
if ($trunk.length && !$(this).hasClass("none")) {
1379+
setTimeout(() => {
1380+
const $boxs = $(".upsale-buttons.boxs");
1381+
if ($boxs.is(":visible")) {
1382+
openNextAccordion($boxs);
1383+
}
1384+
}, 600);
1385+
}
13501386
});
13511387
function resetBoxConfigDefaults() {
13521388
const $amountButtons = $(".box-config .amount-button");
@@ -1519,7 +1555,7 @@ function createModelInfo() {
15191555
console.log("model", model);
15201556
if ($(".model-info")[0]) return;
15211557
const infoWrap = $("<div>").addClass("model-info").prependTo(".col-xs-12.col-lg-6.p-info-wrapper");
1522-
$("<div>").addClass("header-info").text("Garancia kompatibility s Va\u0161\xEDm vozidlom").appendTo(infoWrap);
1558+
$("<div>").addClass("header-info").text(language2 === "cs" ? "Z\xE1ruka kompatibility s Va\u0161\xEDm vozidlem" : "Garancia kompatibility s Va\u0161\xEDm vozidlom").appendTo(infoWrap);
15231559
$("<div>").addClass("model-text").text(model).appendTo(infoWrap);
15241560
$(".setup-model").on("click", function() {
15251561
console.log("setup model");
@@ -1679,7 +1715,7 @@ function updateUpsale($this, event) {
16791715
$($this).addClass("active");
16801716
$("select.surcharge-parameter.parameter-id-" + value[0]).val(value[1]);
16811717
}
1682-
if ($($this).hasClass("config")) {
1718+
if ($($this).hasClass("config") && !$($this).hasClass("none")) {
16831719
$($this).parents(".upsale-Banner").addClass("showConf");
16841720
}
16851721
if (value[0] === "conf1" || value[0] === "conf2") {
@@ -1774,11 +1810,9 @@ function updateUpsale($this, event) {
17741810
function updateBoxPrice() {
17751811
$(".box-config .parameter-wrap").each(function() {
17761812
const price2 = Number($(this).find(".price.price-standart").attr("data-price"));
1777-
const addPrice = Number($(this).find(".button.option-button.text.active .price").attr("data-price"));
1813+
const addPrice = Number($(this).find(".button.option-button.text.active .price").attr("data-price") || 0);
17781814
console.log(price2, addPrice);
1779-
if (addPrice) {
1780-
$(this).find(".price.price-standart").text(NumToPrice(price2 + addPrice));
1781-
}
1815+
$(this).find(".price.price-standart").text(NumToPrice(price2 + addPrice));
17821816
});
17831817
}
17841818
function createUpsaleInfo(texts) {
@@ -1816,17 +1850,46 @@ $("body").on("click", ".button.option-button", function(e) {
18161850
updateButtonTexts();
18171851
}
18181852
}, 200);
1819-
if (!$(".goToAction")[0]) {
1820-
console.log("goToAction");
1821-
$(".upsale-Banner").fadeIn(400);
1822-
$(".upsale-Banner").show();
1823-
$(".upsale-buttons.position-wrap.parameter-cars.parameter-wrap.boxs").hide();
1824-
if ($(".upsale-buttons.position-wrap.trunk .upsale-button.radio.active")[0]) {
1825-
$(".upsale-buttons.position-wrap.parameter-cars.parameter-wrap.boxs").show();
1826-
}
1827-
if (!$(".parameter-id-" + koberce)[0]) {
1828-
$(".upsale-buttons.boxs").show();
1829-
}
1853+
const $currentWrap = $(this).closest(".position-wrap, .parameter-wrap");
1854+
const orderNum = parseInt($currentWrap.find(".order").first().text());
1855+
const isStep0or1 = orderNum === 0 || orderNum === 1;
1856+
const hasNextBtn = $currentWrap.find(".next-step-button").length > 0;
1857+
const isInBoxConfig = !!$currentWrap.closest(".config-wrap, .box-config").length;
1858+
if (hasNextBtn && !isStep0or1 && !isInBoxConfig) {
1859+
setTimeout(() => {
1860+
const allContentWraps = $(".content-wrap").children(".position-wrap, .parameter-wrap");
1861+
const contentIndex = allContentWraps.index($currentWrap);
1862+
let $nextWrap = null;
1863+
if (contentIndex >= 0 && contentIndex < allContentWraps.length - 1) {
1864+
$nextWrap = allContentWraps.eq(contentIndex + 1);
1865+
} else if (contentIndex === -1) {
1866+
const $siblings = $currentWrap.parent().children(".position-wrap, .parameter-wrap");
1867+
const sibIndex = $siblings.index($currentWrap);
1868+
if (sibIndex >= 0 && sibIndex < $siblings.length - 1) {
1869+
$nextWrap = $siblings.eq(sibIndex + 1);
1870+
}
1871+
}
1872+
if ($nextWrap) {
1873+
openNextAccordion($nextWrap);
1874+
} else if (!$(".goToAction")[0]) {
1875+
console.log("goToAction");
1876+
$(".upsale-Banner").fadeIn(400);
1877+
$(".upsale-Banner").show();
1878+
$(".upsale-buttons.position-wrap.parameter-cars.parameter-wrap.boxs").hide();
1879+
if ($(".upsale-buttons.position-wrap.trunk .upsale-button.radio.active")[0]) {
1880+
const $boxs = $(".upsale-buttons.boxs");
1881+
$boxs.show();
1882+
openNextAccordion($boxs);
1883+
} else {
1884+
openNextAccordion($(".upsale-buttons.trunk"));
1885+
}
1886+
if (!$(".parameter-id-" + koberce)[0]) {
1887+
const $boxs = $(".upsale-buttons.boxs");
1888+
$boxs.show();
1889+
openNextAccordion($boxs);
1890+
}
1891+
}
1892+
}, 400);
18301893
}
18311894
});
18321895
function priceActualization2(e) {
@@ -2472,11 +2535,11 @@ $.getJSON(optionData.downloadData, function(data) {
24722535
console.log("setupData:", setupData);
24732536
console.log("setupData.settings:", setupData.settings);
24742537
console.log("setupData.cars:", setupData.cars);
2475-
let language2 = dataLayer[0].shoptet.language;
2538+
let language3 = dataLayer[0].shoptet.language;
24762539
if (dataLayer[0].shoptet.projectId == 704436) {
2477-
language2 = "cs";
2540+
language3 = "cs";
24782541
}
2479-
const texts = setupData.language[language2];
2542+
const texts = setupData.language[language3];
24802543
console.log("setupData.language:", texts);
24812544
initProduct(setupData, texts);
24822545
initModelSelect2(texts, setupData);

0 commit comments

Comments
 (0)