Menu
  • Incl.Excl.
    TAXES
  • Stel je vraag +31 (0)10 333 82 10
    0
    FR
    Garantie du prix le plus bas !
    Livraison aux Pays-Bas et en Belgique
    StapelkortingStapelkorting
    Laagste prijsgarantie!
    Bezorging in NL en België
     bouton de thermostat de luxe M-30

    bouton de thermostat de luxe M-30

    20,34Taxes incluses27,1225% korting
    Faites 3 paiements de €6,78. Meer weten?

    Description du produit

    Informations introuvables

    Spécifications

    Numéro de l'article
    14312
    EAN Code
    6094106837862

    bouton de thermostat de luxe M-30

    Directement disponible
    En stock Directement disponible

    Choose from:

    Utilisez le code de réduction :

    CYBERJANUARI

    Entrez ce code lors du paiement pour activer la réduction de 21%.

    Découvrez les catégories en promotion :

    L'action CYBER Januari est valable jusqu'au 31 janvier.

    Ce produit est également disponible dans d'autres variantes.:

    Gratuit livraison
    Délai de livraison : 1 à 3 jours ouvrables
    Délai de réflexion de 14 jours

    Besoin d'aide pour faire le bon choix ?

    Utilisez l'un de nos outils pratiques.

    Avez-vous une question à propos de se produit.

    Avez-vous une question à propos de se produit.

    Simon est heureux de vous aider et peut répondre à toutes vos questions.

    • Large éventail

      Livraison à partir de notre propre stock
    • Délai de réflexion de 14 jours

      Pas bon = remboursé
    • Venez vous chercher en magasin ?

      Nous sommes ouverts 6 jours par semaine.
    • Livraison rapide aux Pays-Bas et en Belgique

      Geen onverwachte kosten achteraf

    Reviews

    0 évaluations

    bouton de thermostat de luxe M-30

    0 évaluations
    Numéro de l'article
    14312
    EAN Code
    6094106837862

    Quand le service de fret livre-t-il dans votre région ?

    Ne s'applique pas aux envois postaux !

      
    Nous livrons les jours suivants dans votre région :
    Malheureusement, nous ne livrons pas dans votre région.
    Veuillez nous contacter pour une solution adaptée.
    Veuillez entrer un code postal valide.

    Évaluer Best-Design bouton de thermostat de luxe M-30

    Meld je aan voor onze nieuwsbrief
    S'abonner

    S'inscrire

    L'inscription à notre boutique permettra d'accélérer votre passage à la caisse lors de vos prochains achats, d'enregistrer plusieurs adresses, de consulter ou de suivre vos commandes, et plus encore.

    S'inscrire

    Votre panier (0)

    Uw ruimte
    Radiator
    Advies

    Deze keuzehulp heeft al meer dan 30.000 anderen geholpen in het kiezen van de beste radiator

    Start de gratis
    radiator keuzehulp

    • Advies gebaseerd op jouw ruimte, budget en wensen
    • Voorkom dure vergissingen met het juiste vermogen voor jouw ruimte
    • Geen eindeloos zoeken meer tussen honderden radiatoren

    Welke ruimte wilt u verwarmen?

    Elke ruimte vraagt om een andere combinatie van vermogen, formaat en design.
    Kies de ruimte dat u wilt verwarmen

    Hoe goed is de isolatie van de ruimte?

    Goede isolatie houdt warmte beter vast, waardoor u minder vermogen nodig heeft.
    Kies de kwaliteit van isolatie

    Wat zijn de afmetingen van de ruimte? (in centimeters)

    We gebruiken dit om het benodigde vermogen te berekenen.
    cm
    cm
    cm

    Hoe wilt u de ruimte verwarmen?

    De manier van verwarmen bepaalt het type en vermogen van de radiator.

    Zijn er momenteel al verwarmingen in de ruimte die u wilt behouden?

    Bestaande radiatoren tellen mee in het totale benodigde vermogen.

    Hoeveel vermogen hebben deze radiatoren samen in Watt

    Zo berekenen we precies wat er aanvullend nodig is.
    Vul hier het vermogen van alle radiatoren samen in Watt
    Watt

    Wat is de gewenste temperatuur van uw ruimte?

    Een hogere temperatuur vraagt om meer vermogen.
    Kies de gewenste temperatuur van isolatie

    Hoeveel radiatoren kunt en wilt u plaatsen in deze ruimte?

    Meer radiatoren betekent dat elk minder vermogen hoeft te leveren.
    Vul hier het aantal radiatoren voor in uw gekozen ruimte in

    Welke kleur wilt u voor op uw radiator(en)?

    Zo krijgt u enkel voorstellen binnen uw eigen smaak.
    Kies de gewenste kleur

    Wilt u een of meerdere verticale of horizontale radiatoren?

    Kies de gewenste vorm

    Zijn er harde eisen voor afmetingen?

    Vink uit wat niet gewenst is bij de afmetingen (breedte x hoogte)
    Breedte (cm)
    Hoogte (cm)
    Niet gewenst

    Hoe wilt u dat de radiatoren eruit komen te zien?

    Maak een keuze over de uitstraling van de radiator(en)

    Hoe wil je de radiator(en) aansluiten?

    Maak een keuze over de aansluiting van de radiator(en)

    Perfect! We hebben ideale radiatoren gevonden

    Speciaal geselecteerd voor jouw ruimte

    delivery
    Snelle leveringin Nederland en België
    time
    14 dagenbedenktijd
    security
    Laagsteprijsgarantie
    bell
    Je bespaart tot 80% met onze aanbiedingen
    Prijs filter
    0 - €1000
    01000
    Producten laden...

    Voor een optimale circulatie heeft u ook een stromingsbuis nodig.

    Wilt u een stromingsbuis toevoegen voor optimale circulatie?

    Geen geschikte radiator gevonden voor het benodigde wattage

    Het benodigde wattage ({wattage} Watt per radiator) kan niet worden gehaald met de gekozen aantal radiatoren.

    Wilt u een extra radiator plaatsen om het totale wattage te behalen?

    Hoe wilt u de radiator aansluiten?

    Wij adviseren u bij deze radiator een aansluitset mee te bestellen, zodat u alle onderdelen heeft om de radiator op te hangen en aan te sluiten.

    Welke situatie is van toepassing?

    Maak je bestelling compleet

    Kies net zoals vele een totaalpakket.

    Kies uw aansluitset

    Aansluitsets laden...

    Heeft u een (thermostatische) aansluitset nodig?

    Nog een ruimte verwarmen of afrekenen?

    truck
    Snelle
    levering
    return
    14 dagen
    bedenktijd
    rating
    Laagste
    prijsgarantie
    Payment iconPayment iconPayment iconPayment iconPayment iconPayment iconPayment iconPayment iconPayment iconPayment iconPayment iconPayment iconPayment icon
    truckSnelle levering
    return30 dagen retourrecht
    radiator keuzehulp", subtitle: "Hier kunnen we een subtitel plaatsen.", benefit_1: "Advies gebaseerd op jouw ruimte, budget en wensen", benefit_2: "Voorkom dure vergissingen met het juiste vermogen voor jouw ruimte", benefit_3: "Geen eindeloos zoeken meer tussen honderden radiatoren", cta_button: "Start gratis keuzehulp", footer_note: "Krijg binnen enkele minuten het beste advies, goedgekeurd en opgesteld door specialisten", // Step 2 translations step2_title: "Welke ruimte wilt u verwarmen?", step2_expert_message: "Elke ruimte vraagt om een andere combinatie van vermogen, formaat en design.", step2_more_info: "Meer informatie", step2_question_text: "Kies de ruimte dat u wilt verwarmen", step2_question_label: "Kies de ruimte dat u wilt verwarmen", room_woonkamer: "Woonkamer", room_woonkamer_desc: "Grote ruimte met veel comfort", room_slaapkamer: "Slaapkamer", room_slaapkamer_desc: "Rustig en gelijkmatige warmte", room_keuken: "Keuken", room_keuken_desc: "Snelle opwarming gewenst", room_badkamer: "Badkamer", room_badkamer_desc: "Hoge vochtigheid en warmte", room_kantoor: "Kantoor/studeerkamer", room_kantoor_desc: "Constante temperatuur", room_gang: "Gang/hal", room_gang_desc: "Doorloop ruimte", next_button: "Volgende vraag", progress_step1: "Uw ruimte", progress_step2: "Radiator", progress_step3: "Advies", // Step 3 translations step3_title: "Hoe goed is de isolatie van de ruimte?", step3_expert_message: "Goede isolatie houdt warmte beter vast, waardoor u minder vermogen nodig heeft.", step3_more_info: "Meer informatie", step3_question_text: "Kies de kwaliteit van isolatie", isolation_slecht: "Slecht", isolation_slecht_desc: "Oude woning, veel tocht", isolation_normaal: "Normaal", isolation_normaal_desc: "Standaard isolatie", isolation_goed: "Goed", isolation_goed_desc: "Moderne isolatie", // Step 4 translations step4_title: "Wat zijn de afmetingen van de ruimte? (in centimeters)", step4_expert_message: "We gebruiken dit om het benodigde vermogen te berekenen.", step4_more_info: "Meer informatie", dimension_height: "Vul de hoogte in centimeters in", dimension_width: "Vul de breedte in centimeters in", dimension_length: "Vul de lengte in centimeters in", // Step 5 translations step5_title: "Hoe wilt u de ruimte verwarmen?", step5_expert_message: "De manier van verwarmen bepaalt het type en vermogen van de radiator.", step5_more_info: "Meer informatie", heating_elektrisch: "Elektrisch verwarmen", heating_elektrisch_desc: "Elektrisch verwarmen gebruikt elektriciteit om warmte op te wekken, is duurzaam, energiezuinig, flexibel en gasvrij.", heating_cv_ketel: "CV-Ketel", heating_cv_ketel_desc: "Een cv-ketel verwarmt water centraal voor radiatoren en kranen, biedt snel comfort en efficiëntie.", heating_stadsverwarming: "Stadsverwarming", heating_stadsverwarming_desc: "Stadsverwarming levert warmte vanuit een centraal netwerk, zonder eigen ketel, efficiënt en milieuvriendelijk verwarmd.", heating_warmtepomp: "Warmtepomp", heating_warmtepomp_desc: "Een warmtepomp haalt energie uit lucht, water of grond, biedt duurzame verwarming en bespaart energie.", // Step 6 translations step6_title: "Zijn er momenteel al verwarmingen in de ruimte die u wilt behouden?", step6_expert_message: "Bestaande radiatoren tellen mee in het totale benodigde vermogen.", step6_more_info: "Meer informatie", keep_heating_yes: "Ja, Ik wil graag één of meerdere radiatoren behouden.", keep_heating_no: "Nee, Ik wil geen radiatoren behouden.", // Step 7 translations step7_title: "Hoeveel vermogen hebben deze radiatoren samen in Watt", step7_expert_message: "Zo berekenen we precies wat er aanvullend nodig is.", step7_more_info: "Meer informatie", step7_question_text: "Vul hier het vermogen van alle radiatoren samen in Watt", radiator_power_label: "Vul het vermogen in Watt in", // Step 8 translations step8_title: "Wat is de gewenste temperatuur van uw ruimte?", step8_expert_message: "Een hogere temperatuur vraagt om meer vermogen.", step8_more_info: "Meer informatie", step8_question_text: "Kies de gewenste temperatuur van isolatie", temperature_placeholder: "Kies het aantal graden", // Step 9 translations step9_title: "Hoeveel radiatoren kunt en wilt u plaatsen in deze ruimte?", step9_expert_message: "Meer radiatoren betekent dat elk minder vermogen hoeft te leveren.", step9_more_info: "Meer informatie", step9_question_text: "Vul hier het aantal radiatoren voor in uw gekozen ruimte in", radiator_count_label: "Vul het aantal radiatoren in", // Step 10 translations step10_title: "Welke kleur wilt u voor op uw radiator(en)?", step10_expert_message: "Zo krijgt u enkel voorstellen binnen uw eigen smaak.", step10_more_info: "Meer informatie", step10_question_text: "Kies de gewenste kleur", color_zwart: "Zwart", color_wit: "Wit", color_antraciet: "Antraciet", color_chroom: "Chroom", color_goud: "Goud", // Step 11 translations step11_title_single: "Wilt u een verticale of horizontale radiator?", step11_title_multiple: "Wilt u een of meerdere verticale of horizontale radiatoren?", step11_expert_message: "Waarom vragen we om een verticale of horizontale radiator?", step11_more_info: "Meer informatie", step11_question_text: "Kies de gewenste vorm", orientation_vertical: "Verticale radiatoren", orientation_horizontal: "Horizontale radiatoren", // Step 12 translations step12_title: "Hoe wilt u dat de radiatoren eruit komen te zien?", step12_expert_message: "Waarom vragen we om de uitstraling van de radiator?", step12_more_info: "Meer informatie", step12_question_text: "Maak een keuze over de uitstraling van de radiator(en)", step12_size_question_text: "Vink uit wat niet gewenst is bij de afmetingen (breedte x hoogte)", step12_size_title: "Zijn er harde eisen voor afmetingen?", variant_ribbel: "Geribbeld (standaard) voorzijde", variant_vlak: "Vlakke voorzijde", variant_groef: "Gegroefde (gelijnde) voorzijde", // Step 13 translations step13_title_single: "Heeft u een (thermostatische) aansluitset nodig?", step13_title_multiple: "Heeft u een (thermostatische) aansluitset nodig?", step13_title_single_paneel: "Heeft u een (thermostatische) aansluitset nodig?", step13_title_multiple_paneel: "Heeft u een (thermostatische) aansluitset nodig?", step13_expert_message: "Waarom vragen we hoe u de radiatoren wil aansluiten?", step13_more_info: "Meer informatie", step13_question_text: "Maak een keuze over de aansluiting van de radiator(en)", connection_boven: "Zij-boven aansluitingen", connection_onder: "Zij-onder aansluitingen", connection_middenonder: "Midden-onder aansluiting", connection_rechtlinks_onder: "Rechts- of linksonder aansluiting", connection_zijkant: "Aan de zijkanten van de radiator", // Step 13a translations step13a_title: "Hoe wil je de radiator(en) aansluiten?", step13a_question_text: "Maak een keuze over de aansluiting van de radiator(en)", // Step 14 translations step14_title: "Wilt u de thermostaatknop op een andere aansluiting monteren dan op de onderblokset zelf?", step14_expert_message: "Waarom vragen we of u een aansluitset nodig heeft?", step14_more_info: "Meer informatie", insert_product_title: "ECA Insert voor uw radiatoren", insert_product_subtitle: "Speciaal geselecteerd voor onderblokset installaties", aansluitset_ja: "Ja", aansluitset_nee: "Nee", // Step 15 translations step15_title_default: "Welke situatie is van toepassing?", step15_title_zijkant: "U heeft gekozen voor aansluiten aan de zijkanten van de radiator. Welke situatie is van toepassing?", step15_title_onder: "U heeft gekozen voor aansluiten aan de onderkant van de radiator. Welke situatie is van toepassing?", step15_title_boven: "U heeft gekozen voor aansluiten aan de bovenkant van de radiator. Welke situatie is van toepassing?", step15_expert_message: "Aansluiten aan de bovenkant wordt afgeraden, tenzij dit gebeurt in combinatie met een stromingsbuis. Zonder stromingsbuis kan de circulatie worden belemmerd, wat het rendement verlaagt. De stromingsbuis is in de volgende stap te selecteren.", step15_more_info: "Meer informatie", leidingen_plafond: "Leidingen uit het plafond", leidingen_vloer: "Leidingen uit de vloer", leidingen_wand: "Leidingen uit de wand", leidingen_parallel: "Leidingen parallel aan de wand", // Step 16 translations step16_title: "Perfect! We hebben ideale radiatoren gevonden", step16_subtitle: "Speciaal geselecteerd voor jouw ruimte", free_shipping: "Snelle levering", shipping: "in Nederland en België", delivery_days: "14 dagen", delivery_time: "bedenktijd", lowest_price: "Laagste", price_guarantee: "prijsgarantie", savings_text: "Je bespaart tot 80% met onze aanbiedingen", get_advice: "\n" + " \n" + " Advies opslaan", price_filter: "Prijs filter", all_products: "Alle (3)", most_sold: "★ Meest verkocht", best_choice: "♥ Beste keuze", for_you: "◆ Voor jou", continue_shopping: "Verder winkelen", // Extra radiator step translations extra_radiator_title: "Geen geschikte radiator gevonden voor het benodigde wattage", extra_radiator_subtitle: "Het benodigde wattage ({wattage} Watt per radiator) kan niet worden gehaald met de beschikbare radiatoren.", extra_radiator_question: "Wilt u een extra radiator plaatsen om het totale wattage te behalen?", extra_radiator_yes: "Ja, plaats een extra radiator", extra_radiator_no: "Nee, zoek binnen de huidige mogelijkheden", // Step 19 (Final checkout) translations step19_title: "Nog een ruimte verwarmen of afrekenen?", restart_tool: "Restart keuzehulp", direct_checkout: "Direct afrekenen", view_cart: "Bekijk Winkelwagen", // Product page translations choose_this: "+ KIES DEZE!", add_to_cart: "Toevoegen", no_products_found: "Geen producten gevonden met de geselecteerde filters.", try_other_filters: "Probeer andere filterinstellingen.", error_loading_products: "Er is een fout opgetreden bij het laden van de producten.", try_again: "Opnieuw proberen", electric_badge: "ELEKTRISCH", recommended_badge: "#1 AANBEVOLEN", fast_heating: "Snelle opwarming", energy_efficient: "Energiezuinig", thermostat_control: "Thermostaatregeling", timer_function: "Timer Functie", free_shipping_text: "Snelle Levering", return_policy: "14 dagen bedenktijd", delivery_bar_free_shipping: "Snelle levering", delivery_bar_return_policy: "30 dagen retourrecht", delivery_bar_rating: "9.2 klantbeoordeling", // Aansluitset section translations aansluitset_advice: "Wij adviseren u bij deze radiator een aansluitset mee te bestellen, zodat u alle onderdelen heeft om de radiator op te hangen en aan te sluiten.", yes_need_aansluitset: "Ja, die heb ik nodig", no_need_aansluitset: "Nee, die heb ik niet nodig", complete_order_title: "Maak je bestelling compleet", complete_order_subtitle: "Kies net zoals vele een totaalpakket.", choose_aansluitset: "Kies uw aansluitset", loading_aansluitsets: "Aansluitsets laden...", // USP section translations usp_free: "Snelle", usp_shipping: "levering", usp_return_days: "14 dagen", usp_return_policy: "bedenktijd", usp_lowest: "Laagste", usp_price_guarantee: "prijsgarantie", save_amount: "Bespaar €{amount} | {discount}% korting!", // Stock status translations in_stock: "Op voorraad", order_before_3pm: "voor 15:00 besteld = vandaag verzonden", backorder: "Backorder", delivery_info_follows: "Leveringsinfo volgt", not_available: "Niet beschikbaar", stock_unknown: "Voorraad onbekend", // Selection and navigation translations select_more_radiators: "Selecteer nog {count} radiator{plural}", select_more_aansluitsets: "{count} aansluitset{plural}", and: "en", radiators_selected: "{count} radiator{plural} geselecteerd", aansluitsets_selected: "{count} aansluitset{plural} geselecteerd", select_radiators: "Selecteer {count} radiator{plural}", // Plural endings plural_radiator: "en", plural_aansluitset: "s", continue: "Verder", // Error messages error_loading_aansluitsets: "Fout bij het laden van aansluitsets.", error_loading_insert: "Fout bij het laden van het insert product.", error_loading_stromingsbuis: "Fout bij laden van stromingsbuizen.", // Product badges and labels recommended: "Aanbevolen", popular_choice: "Veel gekozen", // Button states loading_btn: "Bezig...", added_to_cart: "✓ Toegevoegd", quantity_added: "✓ {quantity}x Toegevoegd", // Discount text (simple version without percentage) save_amount_simple: "Bespaar €{amount}", // Stromingsbuis texts loading_stromingsbuis: "Stromingsbuizen laden...", no_suitable_stromingsbuis: "Geen geschikte stromingsbuis gevonden.", select_stromingsbuis: "Selecteer stromingsbuis", previous: "Vorige", all: "Alle" }, fr: { page_title: "Outil de Sélection Gratuit - Radiator Outlet", brand_name: "RADIATOR OUTLET.NL", usp_1: "Conseils gratuits dans 5 minutes", usp_2: "Conseils personnels par des experts", usp_3: "Meilleur prix avec garantie qualité", expert_help: "Cet outil de sélection a déjà aidé plus de 30.000 autres à choisir le meilleur radiateur", main_title: "Commencez l'outil de sélection
    de radiateur gratuit", subtitle: "Ici, nous pouvons placer un sous-titre.", benefit_1: "Conseils adaptés à votre espace, budget et souhaits", benefit_2: "Évitez les erreurs coûteuses grâce à la puissance adaptée à votre espace", benefit_3: "Fini les recherches interminables parmi des centaines de radiateurs", cta_button: "Commencer l'outil de sélection gratuit", footer_note: "Obtenez les meilleurs conseils en quelques minutes, approuvés et préparés par des spécialistes", // Step 2 translations step2_title: "Quelle pièce voulez-vous chauffer?", step2_expert_message: "Chaque pièce demande une combinaison différente de puissance, de taille et de design.", step2_more_info: "Plus d'informations", step2_question_text: "Choisissez la pièce que vous voulez chauffer", step2_question_label: "Choisissez la pièce que vous voulez chauffer", room_woonkamer: "Salon", room_woonkamer_desc: "Grande pièce avec beaucoup de confort", room_slaapkamer: "Chambre à coucher", room_slaapkamer_desc: "Chaleur calme et uniforme", room_keuken: "Cuisine", room_keuken_desc: "Réchauffement rapide souhaité", room_badkamer: "Salle de bain", room_badkamer_desc: "Humidité élevée et chaleur", room_kantoor: "Bureau/salle d'étude", room_kantoor_desc: "Température constante", room_gang: "Couloir/hall", room_gang_desc: "Espace de passage", next_button: "Question suivante", progress_step1: "Votre pièce", progress_step2: "Radiateur", progress_step3: "Conseil", // Step 3 translations step3_title: "À quel point l'isolation de la pièce est-elle bonne?", step3_expert_message: "Une bonne isolation retient mieux la chaleur, vous avez donc besoin de moins de puissance.", step3_more_info: "Plus d'informations", step3_question_text: "Choisissez la qualité d'isolation", isolation_slecht: "Mauvais", isolation_slecht_desc: "Vieille maison, beaucoup de courants d'air", isolation_normaal: "Normal", isolation_normaal_desc: "Isolation standard", isolation_goed: "Bon", isolation_goed_desc: "Isolation moderne", // Step 4 translations step4_title: "Quelles sont les dimensions de la pièce? (en centimètres)", step4_expert_message: "Nous utilisons ceci pour calculer la puissance nécessaire.", step4_more_info: "Plus d'informations", dimension_height: "Entrez la hauteur en centimètres", dimension_width: "Entrez la largeur en centimètres", dimension_length: "Entrez la longueur en centimètres", // Step 5 translations step5_title: "Comment voulez-vous chauffer la pièce?", step5_expert_message: "La méthode de chauffage détermine le type et la puissance du radiateur.", step5_more_info: "Plus d'informations", heating_elektrisch: "Chauffage électrique", heating_elektrisch_desc: "Le chauffage électrique utilise l'électricité pour générer de la chaleur, est durable, économe en énergie, flexible et sans gaz.", heating_cv_ketel: "Chaudière centrale", heating_cv_ketel_desc: "Une chaudière centrale chauffe l'eau de manière centralisée pour les radiateurs et les robinets, offre un confort rapide et de l'efficacité.", heating_stadsverwarming: "Chauffage urbain", heating_stadsverwarming_desc: "Le chauffage urbain fournit de la chaleur à partir d'un réseau central, sans chaudière propre, chauffage efficace et respectueux de l'environnement.", heating_warmtepomp: "Pompe à chaleur", heating_warmtepomp_desc: "Une pompe à chaleur extrait l'énergie de l'air, de l'eau ou du sol, offre un chauffage durable et économise l'énergie.", // Step 6 translations step6_title: "Y a-t-il actuellement des chauffages dans la pièce que vous souhaitez conserver?", step6_expert_message: "Les radiateurs existants comptent dans la puissance totale nécessaire.", step6_more_info: "Plus d'informations", keep_heating_yes: "Oui, je souhaite conserver un ou plusieurs radiateurs.", keep_heating_no: "Non, je ne veux pas conserver de radiateurs.", // Step 7 translations step7_title: "Quelle est la puissance de ces radiateurs ensemble en Watts", step7_expert_message: "Ainsi nous calculons précisément ce qui est nécessaire en plus.", step7_more_info: "Plus d'informations", step7_question_text: "Entrez ici la puissance de tous les radiateurs ensemble en Watts", radiator_power_label: "Entrez la puissance en Watts", // Step 8 translations step8_title: "Quelle est la température souhaitée de votre pièce?", step8_expert_message: "Une température plus élevée demande plus de puissance.", step8_more_info: "Plus d'informations", step8_question_text: "Choisissez la température souhaitée d'isolation", temperature_placeholder: "Choisissez le nombre de degrés", // Step 9 translations step9_title: "Combien de radiateurs pouvez-vous et voulez-vous placer dans cette pièce?", step9_expert_message: "Plus de radiateurs signifie que chacun doit fournir moins de puissance.", step9_more_info: "Plus d'informations", step9_question_text: "Entrez ici le nombre de radiateurs pour votre pièce choisie", radiator_count_label: "Entrez le nombre de radiateurs", // Step 10 translations step10_title: "Quelle couleur voulez-vous pour votre/vos radiateur(s)?", step10_expert_message: "Ainsi vous n'obtenez que des suggestions selon votre propre goût.", step10_more_info: "Plus d'informations", step10_question_text: "Choisissez la couleur souhaitée", color_zwart: "Noir", color_wit: "Blanc", color_antraciet: "Anthracite", color_chroom: "Chrome", color_goud: "Or", // Step 11 translations step11_title_single: "Voulez-vous un radiateur vertical ou horizontal?", step11_title_multiple: "Voulez-vous un ou plusieurs radiateurs verticaux ou horizontaux?", step11_expert_message: "Pourquoi demandons-nous un radiateur vertical ou horizontal?", step11_more_info: "Plus d'informations", step11_question_text: "Choisissez la forme souhaitée", orientation_vertical: "Radiateurs verticaux", orientation_horizontal: "Radiateurs horizontaux", // Step 12 translations step12_title: "Comment voulez-vous que les radiateurs apparaissent?", step12_expert_message: "Pourquoi demandons-nous l'apparence du radiateur?", step12_more_info: "Plus d'informations", step12_question_text: "Faites un choix sur l'apparence du/des radiateur(s)", step12_size_question_text: "Cochez ce qui n'est pas souhaité pour les dimensions (largeur x hauteur)", step12_size_title: "Y a-t-il des exigences strictes pour les dimensions ?", variant_ribbel: "Façade nervurée (standard)", variant_vlak: "Façade plate", variant_groef: "Façade rainurée (lignes)", // Step 13 translations step13_title_single: "Comment voulez-vous connecter le radiateur?", step13_title_multiple: "Comment voulez-vous connecter les radiateurs?", step13_title_single_paneel: "Comment voulez-vous connecter le radiateur panneau?", step13_title_multiple_paneel: "Comment voulez-vous connecter les radiateurs panneaux?", step13_expert_message: "Pourquoi demandons-nous comment connecter les radiateurs?", step13_more_info: "Plus d'informations", step13_question_text: "Faites un choix sur la connexion du/des radiateur(s)", connection_boven: "Sur les connexions latérales supérieures du radiateur", connection_onder: "Sur les connexions latérales inférieures du radiateur", connection_middenonder: "Connexion milieu-bas", connection_rechtlinks_onder: "Connexion droite ou gauche en bas", connection_zijkant: "Sur les côtés du radiateur", // Step 13a translations step13a_title: "Comment voulez-vous connecter le/les radiateur(s)?", step13a_question_text: "Faites un choix sur la connexion du/des radiateur(s)", // Step 14 translations step14_title: "Souhaitez-vous monter la tête thermostatique sur un autre raccordement que sur le bloc de raccordement inférieur lui-même ?", step14_expert_message: "Pourquoi demandons-nous si vous avez besoin d'un kit de connexion?", step14_more_info: "Plus d'informations", insert_product_title: "ECA Insert pour vos radiateurs", insert_product_subtitle: "Spécialement sélectionné pour les installations de blocs de raccordement inférieurs", aansluitset_ja: "Oui", aansluitset_nee: "Non", // Step 15 translations step15_title_default: "Quelle situation s'applique?", step15_title_zijkant: "Vous avez choisi de connecter sur les côtés du radiateur. Quelle situation s'applique?", step15_title_onder: "Vous avez choisi de connecter en bas du radiateur. Quelle situation s'applique?", step15_title_boven: "Vous avez choisi de connecter en haut du radiateur. (Cette option n'est pas recommandée pour les radiateurs verticaux) Quelle situation s'applique?", step15_expert_message: "Le raccordement par le haut est déconseillé, sauf s’il est réalisé avec une canne de déflexion (tube plongeur). Sans canne de déflexion, la circulation peut être entravée, ce qui réduit le rendement. La canne de déflexion peut être sélectionnée à l’étape suivante.", step15_more_info: "Plus d'informations", leidingen_plafond: "Conduites depuis le plafond", leidingen_vloer: "Conduites depuis le sol", leidingen_wand: "Conduites sortant du mur", leidingen_parallel: "Conduites parallèles au mur", // Step 16 translations step16_title: "Parfait! Nous avons trouvé des radiateurs idéaux", step16_subtitle: "Spécialement sélectionnés pour votre pièce", free_shipping: "Livraison", shipping: "rapide", delivery_days: "14 jours", delivery_time: "réflexion", lowest_price: "Prix", price_guarantee: "le plus bas", savings_text: "Vous économisez jusqu'à 80% avec nos offres", get_advice: "\n" + " \n" + " Sauvegarder conseil", price_filter: "Filtre prix", all_products: "Tous", most_sold: "★ Plus vendus", best_choice: "♥ Meilleur choix", for_you: "◆ Pour vous", continue_shopping: "Continuer shopping", // Extra radiator step translations extra_radiator_title: "Aucun radiateur approprié trouvé pour le wattage requis", extra_radiator_subtitle: "Le wattage requis ({wattage} Watt par radiateur) ne peut pas être atteint avec les radiateurs disponibles.", extra_radiator_question: "Voulez-vous placer un radiateur supplémentaire pour atteindre le wattage total?", extra_radiator_yes: "Oui, placer un radiateur supplémentaire", extra_radiator_no: "Non, rechercher dans les possibilités actuelles", step19_title: "Chauffer une autre pièce ou payer ?\n", restart_tool: "Recommencer l'aide au choix", direct_checkout: "Payer directement", view_cart: "Voir le panier", // Product page translations choose_this: "+ CHOISIR CELUI-CI!", add_to_cart: "Ajouter", no_products_found: "Aucun produit trouvé avec les filtres sélectionnés.", try_other_filters: "Essayez d'autres paramètres de filtre.", error_loading_products: "Une erreur s'est produite lors du chargement des produits.", try_again: "Réessayer", electric_badge: "ÉLECTRIQUE", recommended_badge: "#1 RECOMMANDÉ", fast_heating: "Chauffage rapide", energy_efficient: "Économe en énergie", thermostat_control: "Contrôle thermostat", timer_function: "Fonction minuterie", free_shipping_text: "Livraison rapide", return_policy: "14 jours de réflexion", delivery_bar_free_shipping: "Gratuit livraison", delivery_bar_return_policy: "30 jours droit de retour", delivery_bar_rating: "9.2 évaluation client", // Aansluitset section translations aansluitset_advice: "Nous vous conseillons de commander un kit de connexion avec ce radiateur, afin d'avoir toutes les pièces pour suspendre et connecter le radiateur.", yes_need_aansluitset: "Oui, j'en ai besoin", no_need_aansluitset: "Non, je n'en ai pas besoin", complete_order_title: "Complétez votre commande", complete_order_subtitle: "Choisissez comme beaucoup un package complet.", choose_aansluitset: "Choisissez votre kit de connexion", loading_aansluitsets: "Chargement des kits de connexion...", // USP section translations usp_free: "rapide", usp_shipping: "livraison", usp_return_days: "14 jours", usp_return_policy: "réflexion", usp_lowest: "Prix le plus bas", usp_price_guarantee: "garanti", save_amount: "Économisez €{amount} | {discount}% de réduction!", // Stock status translations in_stock: "En stock", order_before_3pm: "commandé avant 15h00 = expédié aujourd'hui", backorder: "Commande en attente", delivery_info_follows: "Informations de livraison suivront", not_available: "Non disponible", stock_unknown: "Stock inconnu", // Selection and navigation translations select_more_radiators: "Sélectionnez encore {count} radiateur{plural}", select_more_aansluitsets: "{count} kit{plural} de connexion", and: "et", radiators_selected: "{count} radiateur{plural} sélectionné{plural}", aansluitsets_selected: "{count} kit{plural} de connexion sélectionné{plural}", select_radiators: "Sélectionnez {count} radiateur{plural}", // Plural endings plural_radiator: "s", plural_aansluitset: "s", continue: "Continuer", // Error messages error_loading_aansluitsets: "Erreur lors du chargement des kits de connexion.", error_loading_insert: "Erreur lors du chargement du produit d'insertion.", error_loading_stromingsbuis: "Erreur lors du chargement des tubes de flux.", // Product badges and labels recommended: "Recommandé", popular_choice: "Choix populaire", // Button states loading_btn: "En cours...", added_to_cart: "✓ Ajouté", quantity_added: "✓ {quantity}x Ajouté", // Discount text (simple version without percentage) save_amount_simple: "Économisez €{amount}", // Stromingsbuis texts loading_stromingsbuis: "Chargement des tubes de flux...", no_suitable_stromingsbuis: "Aucun tube de flux approprié trouvé.", select_stromingsbuis: "Sélectionnez le tube de flux", previous: "Précédent", all: "Tous" } }; let currentLanguage = 'fr';let currentSlide = 0; let currentProgress = 10; // Start at 10% let isOnderbloksetSelected = false; // Track if onderblokset is chosen // Initialize dataLayer if it doesn't exist window.dataLayer = window.dataLayer || []; // Helper function to push events to dataLayer function pushDataLayerEvent(eventName, stepData) { window.dataLayer.push({ event: eventName, step_number: parseInt(eventName.replace('keuzetool_step_', '')), step_data: stepData, timestamp: new Date().toISOString() }); console.log('DataLayer event pushed:', eventName, stepData); } function startUSPCarousel() { const carousel = document.querySelector('.usp-carousel'); const slides = document.querySelectorAll('.usp-slide'); const uspBar = document.querySelector('.usp-bar'); // Set each slide width to match the usp-bar width const barWidth = uspBar.offsetWidth; slides.forEach(slide => { slide.style.width = barWidth + 'px'; }); setInterval(() => { currentSlide = (currentSlide + 1) % slides.length; const translateX = -(currentSlide * barWidth); carousel.style.transform = `translateX(${translateX}px)`; }, 3000); // Change slide every 3 seconds } // Helper function to get translated text function translateText(key) { if (translations[currentLanguage] && translations[currentLanguage][key]) { return translations[currentLanguage][key]; } console.warn(`Missing translation for key: ${key} in language: ${currentLanguage}`); return key; // Return key as fallback } function updateTexts() { const elements = document.querySelectorAll('[data-translate]'); elements.forEach(element => { const key = element.getAttribute('data-translate'); if (translations[currentLanguage] && translations[currentLanguage][key]) { // Use innerHTML for elements that might contain HTML (like main_title with
    ) if (key === 'main_title' || key === 'footer_note' || key === 'step2_question_text' || key === 'step3_question_text' || key === 'step7_question_text' || key === 'step8_question_text' || key === 'step9_question_text' || key === 'step10_question_text' || key === 'step11_question_text' || key === 'step12_size_question_text' || key === 'step12_question_text' || key === 'step13_question_text' || key === 'step13a_question_text' || key.startsWith('dimension_') || key.startsWith('radiator_') || key.startsWith('color_') || key.startsWith('orientation_') || key.startsWith('variant_') || key.startsWith('connection_') || key === 'step16_title' || key === 'get_advice' || key.startsWith('delivery_bar_') || key.startsWith('usp_')) { element.innerHTML = translations[currentLanguage][key]; } else { element.textContent = translations[currentLanguage][key]; } }else{ console.warn(`Missing translation for key: ${key} in language: ${currentLanguage}`); } }); // Update page title document.title = translations[currentLanguage].page_title; } function changeLanguage() { const select = document.getElementById('languageSelect'); currentLanguage = select.value; updateTexts(); } function closeModal() { console.log('Close modal clicked'); document.querySelector('.radiator-keuzetool').classList.remove('active'); } function startSelection() { console.log('Start selection clicked'); showStep('step2'); } // Aansluitset products mapping with filtering rules const aansluitsetProducts = { 'https://www.radiator-outlet.nl/nl/oppio-thermostatische-haakse-aansluitingen-tbv-rad.html': { 'kw__aansluiting': ['zijkant'], 'kw__leidingen': ['wand', 'plafond', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/oppio-thermostatische-haakse-aansluitingen-tbv-rad.html#': { 'kw__aansluiting': ['onder'], 'kw__leidingen': ['wand'] }, 'https://www.radiator-outlet.nl/nl/oppio-thermostatische-haakse-aansluitingen-tbv-rad.html##': { 'kw__aansluiting': ['boven'], 'kw__leidingen': ['parallel', 'wand', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/oppio-thermostatische-haakse-aansluitingen-tbv-rad.html###': { 'kw__aansluiting': ['zijkant'], 'kw__leidingen': ['plafond', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/oppio-thermostatische-haakse-aansluitingen-tbv-rad.html####': { 'kw__aansluiting': ['onder'], 'kw__leidingen': ['parallel', 'plafond'] }, 'https://www.radiator-outlet.nl/nl/luxe-chrome-thermostatische-radiator-aansluitset-h.html': { 'kw__aansluiting': ['zijkant'], 'kw__leidingen': ['wand', 'plafond', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/luxe-chrome-thermostatische-radiator-aansluitset-h.html#': { 'kw__aansluiting': ['boven'], 'kw__leidingen': ['parallel', 'wand', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/luxe-chrome-thermostatische-radiator-aansluitset-h.html##': { 'kw__aansluiting': ['onder'], 'kw__leidingen': ['wand'] }, 'https://www.radiator-outlet.nl/nl/luxe-chrome-thermostatische-radiator-aansluitset-h.html###': { 'kw__aansluiting': ['zijkant'], 'kw__leidingen': ['plafond', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/luxe-chrome-thermostatische-radiator-aansluitset-h.html####': { 'kw__aansluiting': ['onder'], 'kw__leidingen': ['parallel', 'plafond'] }, 'https://www.radiator-outlet.nl/nl/luxe-zwarte-thermostatische-radiator-aansluitset-h.html': { 'kw__aansluiting': ['zijkant'], 'kw__leidingen': ['wand', 'plafond', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/luxe-zwarte-thermostatische-radiator-aansluitset-h.html#': { 'kw__aansluiting': ['boven'], 'kw__leidingen': ['parallel', 'wand', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/luxe-zwarte-thermostatische-radiator-aansluitset-h.html##': { 'kw__aansluiting': ['onder'], 'kw__leidingen': ['wand'] }, 'https://www.radiator-outlet.nl/nl/luxe-zwarte-thermostatische-radiator-aansluitset-h.html###': { 'kw__aansluiting': ['zijkant'], 'kw__leidingen': ['plafond', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/luxe-zwarte-thermostatische-radiator-aansluitset-h.html####': { 'kw__aansluiting': ['onder'], 'kw__leidingen': ['parallel', 'plafond'] }, // 'https://www.radiator-outlet.nl/nl/luxe-witte-thermostatische-radiator-aansluitset-ha.html': { // 'kw__aansluiting': ['rechtlinks-onder','zijkant'], // 'kw__leidingen': ['wand'] // }, 'https://www.radiator-outlet.nl/nl/luxe-witte-thermostatische-radiator-aansluitset-ha.html#': { 'kw__aansluiting': ['boven'], 'kw__leidingen': ['parallel', 'wand', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/luxe-witte-thermostatische-radiator-aansluitset-ha.html##': { 'kw__aansluiting': ['onder'], 'kw__leidingen': ['wand'] }, 'https://www.radiator-outlet.nl/nl/luxe-witte-thermostatische-radiator-aansluitset-ha.html###': { 'kw__aansluiting': ['zijkant'], 'kw__leidingen': ['plafond', 'vloer'] }, 'https://www.radiator-outlet.nl/nl/luxe-witte-thermostatische-radiator-aansluitset-ha.html####': { 'kw__aansluiting': ['onder'], 'kw__leidingen': ['parallel', 'plafond'] }, 'https://www.radiator-outlet.nl/nl/oppio-thermostatische-rechte-aansluitingen-tbv-rad.html': { 'kw__aansluiting': ['rechtlinks-onder', 'zijkant'], 'kw__leidingen': 'parallel' }, 'https://www.radiator-outlet.nl/nl/oppio-thermostatische-rechte-aansluitingen-tbv-rad.html#': { 'kw__aansluiting': ['boven'], 'kw__leidingen': 'plafond' }, 'https://www.radiator-outlet.nl/nl/oppio-thermostatische-rechte-aansluitingen-tbv-rad.html##': { 'kw__aansluiting': ['onder'], 'kw__leidingen': 'vloer' }, 'https://www.radiator-outlet.nl/nl/luxe-chrome-thermostatische-radiator-aansluitset-r.html': { 'kw__aansluiting': ['rechtlinks-onder', 'zijkant'], 'kw__leidingen': 'parallel' }, 'https://www.radiator-outlet.nl/nl/luxe-chrome-thermostatische-radiator-aansluitset-r.html#': { 'kw__aansluiting': ['boven'], 'kw__leidingen': 'plafond' }, 'https://www.radiator-outlet.nl/nl/luxe-chrome-thermostatische-radiator-aansluitset-r.html##': { 'kw__aansluiting': ['onder'], 'kw__leidingen': 'vloer' }, 'https://www.radiator-outlet.nl/nl/luxe-zwarte-thermostatische-radiator-aansluitset-r.html': { 'kw__aansluiting': ['rechtlinks-onder', 'zijkant'], 'kw__leidingen': 'parallel' }, 'https://www.radiator-outlet.nl/nl/luxe-zwarte-thermostatische-radiator-aansluitset-r.html#': { 'kw__aansluiting': ['boven'], 'kw__leidingen': 'plafond' }, 'https://www.radiator-outlet.nl/nl/luxe-zwarte-thermostatische-radiator-aansluitset-r.html##': { 'kw__aansluiting': ['onder'], 'kw__leidingen': 'vloer' }, 'https://www.radiator-outlet.nl/nl/luxe-witte-thermostatische-radiator-aansluitset-re.html': { 'kw__aansluiting': ['rechtlinks-onder', 'zijkant'], 'kw__leidingen': 'parallel' }, 'https://www.radiator-outlet.nl/nl/luxe-witte-thermostatische-radiator-aansluitset-re.html#': { 'kw__aansluiting': ['boven'], 'kw__leidingen': 'plafond' }, 'https://www.radiator-outlet.nl/nl/luxe-witte-thermostatische-radiator-aansluitset-re.html##': { 'kw__aansluiting': ['onder'], 'kw__leidingen': 'vloer' }, 'https://www.radiator-outlet.nl/nl/universele-chrome-radiator-aansluitset-midden-onde.html': { 'kw__aansluiting': ['middenonder', 'rechtlinks-onder'], 'kw__leidingen': 'vloer' }, 'https://www.radiator-outlet.nl/nl/oppio-universele-radiator-aansluitset-zwart-midden.html': { 'kw__aansluiting': ['middenonder', 'rechtlinks-onder'], 'kw__leidingen': 'vloer' }, 'https://www.radiator-outlet.nl/nl/universele-witte-radiator-aansluitset-midden-onder.html': { 'kw__aansluiting': ['middenonder', 'rechtlinks-onder'], 'kw__leidingen': 'vloer' }, 'https://www.radiator-outlet.nl/nl/oppio-universele-chrome-radiator-aansluitset.html': { 'kw__aansluiting': ['middenonder', 'rechtlinks-onder'], 'kw__leidingen': ['wand', 'plafond'] }, 'https://www.radiator-outlet.nl/nl/universele-zwarte-radiator-aansluitset-midden-onde.html': { 'kw__aansluiting': ['middenonder', 'rechtlinks-onder'], 'kw__leidingen': ['wand', 'plafond'] }, 'https://www.radiator-outlet.nl/nl/universele-witte-radiator-aansluitset-mi-134802606.html': { 'kw__aansluiting': ['middenonder', 'rechtlinks-onder'], 'kw__leidingen': ['wand', 'plafond'] }, }; // Function to toggle insert product selection in step 14 function toggleInsertSelection() { const jaRadio = document.getElementById('aansluitset_ja'); const insertSection = document.getElementById('insertProductSection'); if (jaRadio && jaRadio.checked && insertSection) { insertSection.style.display = 'block'; loadInsertProduct(); } else if (insertSection) { insertSection.style.display = 'none'; } // Update next button state updateNextButtonState(); } function showStep(stepId) { const container = document.querySelector('.container'); // Remove previous step classes from container container.classList.remove('step1', 'step2', 'step3'); // Add current step class to container container.classList.add(stepId); // Hide all steps document.querySelectorAll('.step').forEach(step => { step.classList.remove('active'); }); // Show the requested step document.getElementById(stepId).classList.add('active'); // Make next button sticky with JavaScript makeNextButtonSticky(); // Handle conditional color options for step 10 if (stepId === 'step10') { showConditionalColors(); } // Handle conditional step 11 and dynamic title if (stepId === 'step11') { updateStep11Title(); } // Handle size filtering step if (stepId === 'step12-size') { populateSizeFilterOptions(); } // Handle conditional step 12 variant options if (stepId === 'step12') { updateVariantOptions(); } // Handle conditional step 13a and dynamic connection options if (stepId === 'step13a') { updateConnectionOptions(); } // Handle conditional step 13 and dynamic options if (stepId === 'step13') { updateStep13Title(); } // Handle conditional step 15 and dynamic title if (stepId === 'step15') { updateStep15Title(); updateLeidingenOptions(); } // Handle step 16 product results if (stepId === 'step16') { // Get required radiator count and create footer const formData = getCurrentFormData(); requiredRadiatorCount = parseInt(formData.radiator_count) || 1; // Create the selection footer immediately when step 16 loads createSelectionFooter(); // Load products after a short delay to allow the step to render setTimeout(() => { fetchAndDisplayProducts(true); }, 100); } // Handle step 16a stromingsbuis selection if (stepId === 'step16a') { // Add radio button event listeners for stromingsbuis choice setupStromingsbuisRadioListeners(); } // Update progress bar based on step (19 steps total, ~5.26% per step) if (stepId === 'step1') { setProgress(5); } else if (stepId === 'step2') { setProgress(11); } else if (stepId === 'step3') { setProgress(16); } else if (stepId === 'step4') { setProgress(21); } else if (stepId === 'step5') { setProgress(26); } else if (stepId === 'step6') { setProgress(32); } else if (stepId === 'step7') { setProgress(37); } else if (stepId === 'step8') { setProgress(42); } else if (stepId === 'step9') { setProgress(47); } else if (stepId === 'step10') { setProgress(53); } else if (stepId === 'step11') { setProgress(58); } else if (stepId === 'step12-size') { setProgress(60); } else if (stepId === 'step12') { setProgress(63); } else if (stepId === 'step13a') { setProgress(68); } else if (stepId === 'step13') { setProgress(74); } else if (stepId === 'step14') { setProgress(84); } else if (stepId === 'step15') { setProgress(79); } else if (stepId === 'step16') { setProgress(89); // Push dataLayer event for reaching product results pushDataLayerEvent('keuzetool_step_16', { reached_product_results: true }); } else if (stepId === 'step17') { setProgress(68); } else if (stepId === 'step18') { setProgress(79); // Load aansluitset products when step18 is shown loadAansluitsetProducts(); } else if (stepId === 'step19') { setProgress(100); } } function updateProgressBar(percentage) { const progressFill = document.getElementById('progressFill'); const progressLabels = document.querySelectorAll('.progress-label'); const progressDots = document.querySelectorAll('.progress-dot'); // Remove active class from all labels and dots progressLabels.forEach(label => label.classList.remove('active')); progressDots.forEach(dot => dot.classList.remove('active')); // Update progress bar width progressFill.style.width = percentage + '%'; // Update active labels based on progress - keep previous steps active if (percentage > 0) { progressLabels[0].classList.add('active'); // Uw ruimte } if (percentage > 33) { progressLabels[1].classList.add('active'); // Radiator } if (percentage > 66) { progressLabels[2].classList.add('active'); // Advies } // Update active dots based on progress if (percentage >= 50) { progressDots[0].classList.add('active'); // middle dot } if (percentage >= 100) { progressDots[1].classList.add('active'); // end dot } } function setProgress(percentage) { currentProgress = percentage; updateProgressBar(percentage); } function incrementProgress() { currentProgress = Math.min(currentProgress + 10, 100); updateProgressBar(currentProgress); } function decrementProgress() { currentProgress = Math.max(currentProgress - 10, 10); updateProgressBar(currentProgress); } function goBack() { const currentStep = document.querySelector('.step.active'); if (currentStep.id === 'step2') { showStep('step1'); } else if (currentStep.id === 'step3') { showStep('step2'); } else if (currentStep.id === 'step4') { showStep('step3'); } else if (currentStep.id === 'step5') { showStep('step4'); } else if (currentStep.id === 'step6') { showStep('step5'); } else if (currentStep.id === 'step7') { showStep('step6'); } else if (currentStep.id === 'step8') { // Check if we came from step 7 or should go back to step 6 const keepExistingValue = document.querySelector('input[name="keep_existing"]:checked')?.value; if (keepExistingValue === 'yes') { showStep('step7'); } else { showStep('step6'); } } else if (currentStep.id === 'step9') { showStep('step8'); } else if (currentStep.id === 'step10') { showStep('step9'); } else if (currentStep.id === 'step11') { showStep('step10'); } else if (currentStep.id === 'step12-size') { showStep('step11'); } else if (currentStep.id === 'step12') { showStep('step11'); } else if (currentStep.id === 'step13a') { showStep('step12'); } else if (currentStep.id === 'step13') { // Check if we came from step13a (connection) or need to go somewhere else const selectedHeating = document.querySelector('input[name="heating"]:checked'); selectedRadiators = []; if (selectedHeating && selectedHeating.value === 'elektrisch') { // For electric heating, step13 shouldn't be reachable normally, but go back to step12 showStep('step16'); } else { // For non-electric heating, go back to step13a (connection step) showStep('step16'); } } else if (currentStep.id === 'step14') { showStep('step18'); } else if (currentStep.id === 'step15') { // Go back to step 13 (connection and aansluitset selection) showStep('step13'); } else if (currentStep.id === 'step16') { // Check heating type to determine where to go back const selectedHeating = document.querySelector('input[name="heating"]:checked'); if (selectedHeating && selectedHeating.value === 'elektrisch') { // For electric heating, go back to step12 (surface variant) showStep('step12'); } else { // For non-electric heating, go back to step13 (aansluitset question) showStep('step13a'); } } else if (currentStep.id === 'step16a') { // Go back to step 15 (pipe situation) showStep('step15'); } else if (currentStep.id === 'step17') { // Go back to step 16 (product results) showStep('step16'); } else if (currentStep.id === 'step18') { // Go back based on whether we came from stromingsbuis step if (shouldShowStromingsbuisStep()) { // Go back to step 16a (stromingsbuis selection) showStep('step16a'); } else { // Go back to step 15 (pipe situation) showStep('step15'); } } else if (currentStep.id === 'step19') { // Go back based on how we reached step 19 const formData = getCurrentFormData(); if (window.isOnderbloksetSelected) { // Came from step 14 (onderblokset flow) showStep('step14'); } else if (shouldShowStromingsbuisStep()) { // Came from step 16a (stromingsbuis selection) showStep('step16a'); } else if (formData.aansluitset_needed === 'ja') { // Came from step 18 (regular aansluitset selected) showStep('step18'); } else { // Came directly from step 13 (no aansluitset needed) showStep('step13'); } } } function nextStep() { const currentStep = document.querySelector('.step.active'); if (currentStep.id === 'step2') { const selectedRoom = document.querySelector('input[name="room"]:checked'); if (selectedRoom) { console.log('Selected room:', selectedRoom.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_2', { room_type: selectedRoom.value }); // Increment progress by 10% incrementProgress(); // Go to isolation quality step showStep('step3'); } } else if (currentStep.id === 'step3') { const selectedIsolation = document.querySelector('input[name="isolation"]:checked'); if (selectedIsolation) { console.log('Selected isolation:', selectedIsolation.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_3', { isolation_quality: selectedIsolation.value }); // Increment progress by 10% incrementProgress(); // Go to dimensions step showStep('step4'); } } else if (currentStep.id === 'step4') { const height = document.getElementById('height').value; const width = document.getElementById('width').value; const length = document.getElementById('length').value; if (height && width && length) { console.log('Dimensions:', {height, width, length}); // Push dataLayer event pushDataLayerEvent('keuzetool_step_4', { room_height: height, room_width: width, room_length: length, room_volume: (height * width * length).toFixed(2) }); // Increment progress by 10% incrementProgress(); // Go to heating type step showStep('step5'); } } else if (currentStep.id === 'step5') { const selectedHeating = document.querySelector('input[name="heating"]:checked'); if (selectedHeating) { console.log('Selected heating:', selectedHeating.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_5', { heating_type: selectedHeating.value }); // Increment progress by 10% incrementProgress(); // Go to keep existing heating step showStep('step6'); } } else if (currentStep.id === 'step6') { const selectedKeepExisting = document.querySelector('input[name="keep_existing"]:checked'); if (selectedKeepExisting) { console.log('Keep existing heating:', selectedKeepExisting.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_6', { keep_existing_radiators: selectedKeepExisting.value }); // Increment progress by 10% incrementProgress(); // Check if user wants to keep existing radiators if (selectedKeepExisting.value === 'yes') { // Go to step 7 for radiator power input showStep('step7'); } else { // Skip step 7 and go directly to step 8 showStep('step8'); } } } else if (currentStep.id === 'step7') { const radiatorPower = document.getElementById('radiator_power').value; if (radiatorPower) { console.log('Radiator power:', radiatorPower); // Push dataLayer event pushDataLayerEvent('keuzetool_step_7', { existing_radiator_power: radiatorPower }); // Increment progress by 10% incrementProgress(); // Go to step 8 for temperature selection showStep('step8'); } } else if (currentStep.id === 'step8') { const selectedTemperature = document.getElementById('desired_temperature').value; if (selectedTemperature) { console.log('Selected temperature:', selectedTemperature); // Push dataLayer event pushDataLayerEvent('keuzetool_step_8', { desired_temperature: selectedTemperature }); // Increment progress by 10% incrementProgress(); // Go to step 9 for radiator count showStep('step9'); } } else if (currentStep.id === 'step9') { const radiatorCount = document.getElementById('radiator_count').value; if (radiatorCount) { console.log('Radiator count:', radiatorCount); // Push dataLayer event pushDataLayerEvent('keuzetool_step_9', { radiator_count: radiatorCount }); // Increment progress by 10% incrementProgress(); // Go to step 10 for color selection showStep('step10'); } } else if (currentStep.id === 'step10') { const selectedColor = document.querySelector('input[name="radiator_color"]:checked'); if (selectedColor) { console.log('Selected color:', selectedColor.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_10', { radiator_color: selectedColor.value }); // Increment progress by 10% incrementProgress(); // Check if we should show step 11 (orientation) - not for bathroom const selectedRoom = document.querySelector('input[name="room"]:checked')?.value; const selectedHeating = document.querySelector('input[name="heating"]:checked')?.value; if (selectedRoom !== 'badkamer') { showStep('step11'); } else { // For bathroom, skip orientation and variant steps, but still show connection steps for non-electric heating if (selectedHeating !== 'elektrisch') { // Skip to connection step for bathroom with non-electric heating showStep('step13a'); } else { // For electric heating in bathroom, generate search directly console.log('Bathroom with electric heating selected, generating product search...'); createProductSearchUrl(); showStep('step16'); } } } } else if (currentStep.id === 'step11') { const selectedOrientation = document.querySelector('input[name="radiator_orientation"]:checked'); if (selectedOrientation) { console.log('Selected orientation:', selectedOrientation.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_11', { radiator_orientation: selectedOrientation.value }); // Increment progress by 10% incrementProgress(); // Go to size filtering step showStep('step12'); } } else if (currentStep.id === 'step12-size') { // Size filtering step - always proceed to step 12 (surface variant) // Increment progress by 10% incrementProgress(); showStep('step12'); } else if (currentStep.id === 'step12') { const selectedVariant = document.querySelector('input[name="radiator_variant"]:checked'); if (selectedVariant) { console.log('Selected variant:', selectedVariant.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_12', { radiator_variant: selectedVariant.value }); // Increment progress by 10% incrementProgress(); // After variant selection, check heating type const selectedHeating = document.querySelector('input[name="heating"]:checked'); if (selectedHeating && selectedHeating.value === 'elektrisch') { // For electric heating, skip connection step and go directly to products createProductSearchUrl(); showStep('step16'); } else { // For non-electric heating, go to connection step showStep('step13a'); } } } else if (currentStep.id === 'step13a') { const selectedConnection = document.querySelector('input[name="radiator_connection"]:checked'); if (selectedConnection) { console.log('Selected connection:', selectedConnection.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_13a', { radiator_connection: selectedConnection.value }); // Increment progress by 10% incrementProgress(); // Go to step 13 for aansluitset question showStep('step16'); } } else if (currentStep.id === 'step13') { const selectedAansluitsetNeeded = document.querySelector('input[name="aansluitset_needed"]:checked'); if (selectedAansluitsetNeeded) { console.log('Selected aansluitset needed:', selectedAansluitsetNeeded.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_13', { aansluitset_needed: selectedAansluitsetNeeded.value }); // Increment progress by 10% incrementProgress(); if (selectedAansluitsetNeeded.value === 'ja') { // User wants aansluitset, go to step 15 for pipe situation showStep('step15'); } else { // User doesn't want aansluitset, go to product results createProductSearchUrl(); showStep('step19'); } } } else if (currentStep.id === 'step14') { const selectedAansluitset = document.querySelector('input[name="aansluitset"]:checked'); if (selectedAansluitset) { console.log('Selected aansluitset:', selectedAansluitset.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_14', { aansluitset: selectedAansluitset.value }); // Increment progress by 10% incrementProgress(); // Go to step 19 (final step) after aansluitset selection showStep('step19'); } } else if (currentStep.id === 'step15') { const selectedLeidingen = document.querySelector('input[name="leidingen"]:checked'); if (selectedLeidingen) { console.log('Selected leidingen:', selectedLeidingen.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_15', { leidingen: selectedLeidingen.value }); // Increment progress by 10% incrementProgress(); // Check if stromingsbuis step should be shown if (shouldShowStromingsbuisStep()) { console.log('Going to stromingsbuis step after leidingen selection'); showStep('step16a'); } else { // Go to step 18 for aansluitset product selection showStep('step18'); } } } else if (currentStep.id === 'step17') { // Handle extra radiator response const extraRadiatorChoice = document.querySelector('input[name="extra_radiator"]:checked'); if (extraRadiatorChoice) { // Push dataLayer event pushDataLayerEvent('keuzetool_step_17', { extra_radiator: extraRadiatorChoice.value }); } handleExtraRadiatorResponse(); } else if (currentStep.id === 'step18') { // Handle aansluitset selection const aansluitsetChoice = document.querySelector('input[name="aansluitset_needed"]:checked'); if (aansluitsetChoice) { // Push dataLayer event pushDataLayerEvent('keuzetool_step_18', { aansluitset_needed: aansluitsetChoice.value }); if (aansluitsetChoice.value === 'no') { // User doesn't want aansluitset, go to step 19 showStep('step19'); } else if (aansluitsetChoice.value === 'yes') { // User wants aansluitset, but need to wait for product selection // This will be handled by selectAansluitset function console.log('Waiting for aansluitset product selection'); } } } else if (currentStep.id === 'step16a') { // Handle stromingsbuis choice const stromingsbuisChoice = document.querySelector('input[name="stromingsbuis_needed"]:checked'); if (stromingsbuisChoice) { console.log('Stromingsbuis choice:', stromingsbuisChoice.value); // Push dataLayer event pushDataLayerEvent('keuzetool_step_16a', { stromingsbuis_needed: stromingsbuisChoice.value }); incrementProgress(); // If "yes" was chosen, check if a product was actually selected if (stromingsbuisChoice.value === 'yes') { const productSelected = document.querySelector('.stromingsbuis-product.selected'); if (!productSelected) { alert('Selecteer eerst een stromingsbuis product'); return; } } // After stromingsbuis step, continue to step18 for aansluitset product selection showStep('step18'); } } } // Handle radio button selection function handleRadioSelection() { const radioButtons = document.querySelectorAll('input[type="radio"]'); radioButtons.forEach(radio => { radio.addEventListener('change', function () { const currentStep = this.closest('.step'); const nextButton = currentStep.querySelector('.next-button'); // Remove selected class from all options in this step currentStep.querySelectorAll('.radio-option,.color-option').forEach(option => { option.classList.remove('selected'); }); // Add selected class to the current option if (this.checked) { this.closest('.radio-option,.color-option').classList.add('selected'); if (nextButton) { nextButton.disabled = false; } // Handle aansluitset selection visibility if (this.name === 'aansluitset_needed') { // For step 18: show/hide aansluitset products (original logic) const productsSection = document.getElementById('aansluitset-products'); if (productsSection) { if (this.value === 'yes') { productsSection.style.display = 'block'; // Disable next button until product is selected if (nextButton) { nextButton.disabled = true; } } else { productsSection.style.display = 'none'; // Enable next button for "no" selection if (nextButton) { nextButton.disabled = false; } } } } } }); }); } // Handle dropdown selection function handleDropdownSelection() { const dropdowns = document.querySelectorAll('select'); dropdowns.forEach(dropdown => { dropdown.addEventListener('change', function () { const currentStep = this.closest('.step'); const nextButton = currentStep.querySelector('.next-button'); // Add valid class when a value is selected if (this.value) { this.classList.add('valid'); if (nextButton) { nextButton.disabled = false; } } else { this.classList.remove('valid'); if (nextButton) { nextButton.disabled = true; } } }); }); } // Handle dimension inputs function handleDimensionInputs() { const dimensionInputs = document.querySelectorAll('.dimension-input'); dimensionInputs.forEach(input => { input.addEventListener('input', function () { const inputGroup = this.closest('.input-group'); const value = parseInt(this.value); const min = parseInt(this.min); const max = parseInt(this.max); // Check if value is valid if (value >= min && value <= max) { this.classList.add('valid'); inputGroup.classList.add('valid'); } else { this.classList.remove('valid'); inputGroup.classList.remove('valid'); } // Check if all dimensions are filled and valid if (this.closest('#step4')) { checkDimensionsComplete(); } else if (this.closest('#step7')) { checkRadiatorPowerComplete(); } else if (this.closest('#step9')) { checkRadiatorCountComplete(); } }); }); } function checkDimensionsComplete() { const step4 = document.getElementById('step4'); if (!step4) return; const height = document.getElementById('height'); const width = document.getElementById('width'); const length = document.getElementById('length'); const nextButton = step4.querySelector('.next-button'); const allValid = height && width && length && height.classList.contains('valid') && width.classList.contains('valid') && length.classList.contains('valid'); if (nextButton) { nextButton.disabled = !allValid; } } function checkRadiatorPowerComplete() { const step7 = document.getElementById('step7'); if (!step7) return; const radiatorPower = document.getElementById('radiator_power'); const nextButton = step7.querySelector('.next-button'); const isValid = radiatorPower && radiatorPower.classList.contains('valid'); if (nextButton) { nextButton.disabled = !isValid; } } function checkRadiatorCountComplete() { const step9 = document.getElementById('step9'); if (!step9) return; const radiatorCount = document.getElementById('radiator_count'); const nextButton = step9.querySelector('.next-button'); const isValid = radiatorCount && radiatorCount.classList.contains('valid'); if (nextButton) { nextButton.disabled = !isValid; } } function showConditionalColors() { // Get the selected room from step 2 const selectedRoom = document.querySelector('input[name="room"]:checked')?.value; // Get all color options const colorOptions = document.querySelectorAll('#step10 .color-option'); // Show/hide colors based on room selection colorOptions.forEach(option => { const colorValue = option.querySelector('input').value; if (colorValue === 'zwart' || colorValue === 'wit') { // Always show black and white option.style.display = 'flex'; } else if (selectedRoom === 'badkamer') { // Show all colors for bathroom option.style.display = 'flex'; } else { // Hide special colors for other rooms option.style.display = 'none'; } }); } async function populateSizeFilterOptions() { const container = document.getElementById('sizeFilterOptions'); if (!container) return; container.innerHTML = '
    Formaten ophalen...
    '; try { // Generate product search URL const searchUrl = createProductSearchUrl(); // Fetch products with JSON format const response = await fetch(searchUrl); const data = await response.json(); // Extract unique size combinations from actual products const sizeCombinations = new Set(); console.log(response, searchUrl, data.products, Object.keys(data.products).length > 0); if (data.products && Object.keys(data.products).length > 0) { // Fetch individual product details to get accurate size information const productPromises = Object.values(data.products).map(async (product) => { console.log(product); if (product.url) { try { const productUrl = baseUrl + "/" + currentLanguage + "/" + product.url + '?format=json'; const productResponse = await fetch(productUrl); const productData = await productResponse.json(); if (productData.product.size && productData.product.size.x && productData.product.size.y) { const width = Math.round(productData.product.size.x); const height = Math.round(productData.product.size.y); sizeCombinations.add(`${width}x${height}`); } } catch (error) { console.error('Error fetching product details:', product.url, error); } } }); // Wait for all product fetches to complete await Promise.all(productPromises); } // Clear loading message container.innerHTML = ''; if (sizeCombinations.size === 0) { container.innerHTML = '
    Geen formaten gevonden
    '; return; } // Sort combinations by width, then height const sortedCombinations = Array.from(sizeCombinations).sort((a, b) => { const [aWidth, aHeight] = a.split('x').map(Number); const [bWidth, bHeight] = b.split('x').map(Number); if (aWidth !== bWidth) return aWidth - bWidth; return aHeight - bHeight; }); // Create options for each unique size combination sortedCombinations.forEach(combination => { const [width, height] = combination.split('x'); const optionDiv = document.createElement('div'); optionDiv.className = 'size-filter-option'; optionDiv.innerHTML = `
    ${width} cm
    ${height} cm
    `; container.appendChild(optionDiv); }); } catch (error) { console.error('Error fetching size options:', error); container.innerHTML = '
    Fout bij laden van formaten
    '; } } function updateStep11Title() { // Get the radiator count from step 9 const radiatorCount = parseInt(document.getElementById('radiator_count')?.value) || 1; const titleElement = document.getElementById('step11-title'); if (titleElement) { // Use single or multiple title based on radiator count const titleKey = radiatorCount === 1 ? 'step11_title_single' : 'step11_title_multiple'; if (translations[currentLanguage] && translations[currentLanguage][titleKey]) { titleElement.textContent = translations[currentLanguage][titleKey]; } } } function updateStep13Title() { // Get the radiator count and heating type const radiatorCount = parseInt(document.getElementById('radiator_count')?.value) || 1; const selectedHeating = document.querySelector('input[name="heating"]:checked')?.value; const selectedRoom = document.querySelector('input[name="room"]:checked')?.value; const selectedOrientation = document.querySelector('input[name="radiator_orientation"]:checked')?.value; const titleElement = document.getElementById('step13-title'); if (titleElement) { console.log(selectedHeating, selectedRoom, selectedOrientation); // Determine if it's a panel radiator (non-electric heating) const isPanelRadiator = selectedHeating !== 'elektrisch' && selectedRoom !== 'badkamer' && selectedOrientation == 'horizontaal'; // Use appropriate title based on count and type let titleKey; if (isPanelRadiator) { titleKey = radiatorCount === 1 ? 'step13_title_single_paneel' : 'step13_title_multiple_paneel'; } else { titleKey = radiatorCount === 1 ? 'step13_title_single' : 'step13_title_multiple'; } if (translations[currentLanguage] && translations[currentLanguage][titleKey]) { titleElement.textContent = translations[currentLanguage][titleKey]; } } } function updateVariantOptions() { // Get the selected heating type and room from previous steps const selectedHeating = document.querySelector('input[name="heating"]:checked')?.value; const selectedRoom = document.querySelector('input[name="room"]:checked')?.value; const ribbelOption = document.querySelector('label[for="variant_ribbel"]'); if (ribbelOption) { // Hide "Geribbeld (standaard) voorzijde" option for electric bathroom radiators if (selectedHeating === 'elektrisch') { ribbelOption.style.display = 'none'; // If this option was selected, deselect it and select the first available option const ribbelInput = document.getElementById('variant_ribbel'); if (ribbelInput && ribbelInput.checked) { ribbelInput.checked = false; // Select the first visible option (variant_glad) const gladInput = document.getElementById('variant_glad'); if (gladInput) { gladInput.checked = true; } } } else { // Show the option for other combinations ribbelOption.style.display = 'block'; } } } function updateConnectionOptions() { // Get the selected orientation const selectedOrientation = document.querySelector('input[name="radiator_orientation"]:checked')?.value; const connectionContainer = document.getElementById('connection-options'); if (!connectionContainer) return; // Clear existing options connectionContainer.innerHTML = ''; // Define connection options based on orientation const verticalOptions = [ {value: 'boven', key: 'connection_boven'}, {value: 'onder', key: 'connection_onder'}, {value: 'middenonder', key: 'connection_middenonder'}, ]; const horizontalOptions = [ {value: 'middenonder', key: 'connection_middenonder'}, {value: 'rechtlinks-onder', key: 'connection_rechtlinks_onder'}, {value: 'zijkant', key: 'connection_zijkant'} ]; // Choose options based on orientation, default to both if no orientation selected yet let optionsToShow = []; if (selectedOrientation === 'verticaal') { optionsToShow = verticalOptions; } else if (selectedOrientation === 'horizontaal') { optionsToShow = horizontalOptions; } else { // If no orientation selected yet (e.g., bathroom), show all options optionsToShow = [...verticalOptions];//, ...horizontalOptions } // Create HTML for options optionsToShow.forEach(option => { const optionHTML = ` `; connectionContainer.innerHTML += optionHTML; }); // Re-initialize radio button handling for new options handleRadioSelection(); } function updateStep15Title() { // Get the selected connection type from step 13 const selectedConnection = document.querySelector('input[name="radiator_connection"]:checked')?.value; const titleElement = document.getElementById('step15-title'); const formData = getCurrentFormData(); if (titleElement) { // Use appropriate title based on connection type let titleKey = 'step15_title_default'; if (selectedConnection === 'zijkant') { titleKey = 'step15_title_zijkant'; } else if (selectedConnection === 'onder' || selectedConnection === 'middenonder' || selectedConnection === 'rechtlinks-onder') { titleKey = 'step15_title_onder'; } else if (selectedConnection === 'boven') { titleKey = 'step15_title_boven'; if (formData.room === 'badkamer') document.querySelector('#step15 .expert-info').style.display = 'block'; } if (translations[currentLanguage] && translations[currentLanguage][titleKey]) { titleElement.textContent = translations[currentLanguage][titleKey]; } } } function updateLeidingenOptions() { // Get the selected connection type from step 13a const selectedConnection = document.querySelector('input[name="radiator_connection"]:checked')?.value; const parallelOption = document.querySelector('label[for="leidingen_parallel"]'); if (parallelOption) { // Hide "leidingen parallel" option for middenonder and rechtlinks-onder connections if (selectedConnection === 'middenonder' || selectedConnection === 'rechtlinks-onder') { parallelOption.style.display = 'none'; // If this option was selected, deselect it and select the first available option const parallelInput = document.getElementById('leidingen_parallel'); if (parallelInput && parallelInput.checked) { parallelInput.checked = false; // Select the first visible option (leidingen_wand) const wandInput = document.getElementById('leidingen_wand'); if (wandInput) { wandInput.checked = true; } } } else { // Show the option for other connection types parallelOption.style.display = 'block'; } } } // Final step action functions function restartTool() { // Reset all form data document.querySelectorAll('input[type="radio"]').forEach(input => { input.checked = false; }); document.querySelectorAll('input[type="number"]').forEach(input => { input.value = ''; }); document.querySelectorAll('select').forEach(select => { select.selectedIndex = 0; }); // Reset selection state (if variables are defined globally) if (typeof selectedRadiators !== 'undefined') { selectedRadiators = []; requiredRadiatorCount = 0; } if (typeof selectedAansluitsets !== 'undefined') { selectedAansluitsets = []; requiredAansluitsetCount = 0; } // Hide selection footer const footer = document.querySelector('.radiator-selection-footer'); if (footer) footer.style.display = 'none'; // Reset progress and go to first step setProgress(5); showStep('step1'); } function directCheckout() { // Here you would typically redirect to your checkout page or handle checkout logic console.log('Direct checkout clicked'); //alert('Direct afrekenen functionaliteit wordt geïmplementeerd'); window.location.href = `/${currentLanguage}/checkout/`; } function viewCart() { // Here you would typically show cart modal or redirect to cart page console.log('View cart clicked'); //alert('Winkelwagen bekijken functionaliteit wordt geïmplementeerd'); window.location.href = `/${currentLanguage}/cart`; } function shouldShowStromingsbuisStep() { const formData = getCurrentFormData(); return formData.room === 'badkamer' && formData.radiator_connection === 'boven'; } let stickyButtonTimeout; function makeNextButtonSticky() { const container = document.querySelector('.radiator-keuzetool .container'); const nextButton = container.querySelector('.step.active .next-button'); if (!container || !nextButton) return; // Remove any existing sticky positioning nextButton.style.position = 'relative'; if (window.innerWidth < 900){ nextButton.style.bottom = ''; nextButton.style.left = ''; nextButton.style.right = ''; nextButton.style.zIndex = ''; nextButton.style.borderRadius = ''; nextButton.style.boxShadow = ''; } const containerRect = container.getBoundingClientRect(); const buttonRect = nextButton.getBoundingClientRect(); // Only make sticky if button would appear above container bottom //if (buttonRect.bottom < containerRect.bottom) { if (window.innerWidth < 900){ nextButton.style.position = 'fixed'; nextButton.style.bottom = `${window.innerHeight - containerRect.bottom - 10}px`; nextButton.style.left = `${containerRect.left}px`; nextButton.style.right = `${window.innerWidth - containerRect.right}px`; nextButton.style.zIndex = '1000'; nextButton.style.borderRadius = '0 0 12px 12px'; nextButton.style.boxShadow = '0 -2px 10px rgba(0,0,0,0.1)'; } /*}else{ // Reset styles if not sticky nextButton.style.position = 'relative'; nextButton.style.bottom = ''; nextButton.style.left = ''; nextButton.style.right = ''; nextButton.style.zIndex = ''; nextButton.style.borderRadius = ''; nextButton.style.boxShadow = ''; }*/ } function debouncedMakeNextButtonSticky() { // Clear existing timeout if (stickyButtonTimeout) { clearTimeout(stickyButtonTimeout); } // Set new timeout stickyButtonTimeout = setTimeout(() => { makeNextButtonSticky(); }, 300); } function setupContentObserver() { const contentElement = document.querySelector('.radiator-keuzetool .content'); if (!contentElement) return; const observer = new MutationObserver((mutations) => { let shouldUpdate = false; mutations.forEach((mutation) => { if (mutation.type === 'childList' || mutation.type === 'attributes' || mutation.type === 'subtree') { shouldUpdate = true; } }); if (shouldUpdate) { debouncedMakeNextButtonSticky(); } }); observer.observe(contentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['class', 'style', 'disabled'] }); console.log('Content observer setup for sticky button'); } function setupStromingsbuisRadioListeners() { const radioButtons = document.querySelectorAll('input[name="stromingsbuis_needed"]'); const productResults = document.getElementById('stromingsbuisResults'); const nextButton = document.querySelector('#step16a .next-button'); radioButtons.forEach(radio => { radio.addEventListener('change', function () { if (nextButton) { nextButton.disabled = false; } // Remove selected class from all options document.querySelectorAll('#step16a .radio-option').forEach(option => { option.classList.remove('selected'); }); // Add selected class to current option if (this.checked) { this.closest('.radio-option').classList.add('selected'); if (this.value === 'yes' && productResults) { // Show product section and load stromingsbuis products productResults.style.display = 'block'; setTimeout(() => { loadStromingsbuisProducts(); }, 100); } else if (productResults) { // Hide product section productResults.style.display = 'none'; } } }); }); } function startKeuzetool() { // Set initial step class on container document.querySelector('.container').classList.add('step1'); // Activate the keuzetool document.querySelector('.radiator-keuzetool').classList.add('active'); // Initialize with default language updateTexts(); // Start the USP carousel startUSPCarousel(); // Initialize radio button handling handleRadioSelection(); // Initialize dimension inputs handling handleDimensionInputs(); // Initialize dropdown handling handleDropdownSelection(); // Initialize progress bar and set initial step setProgress(5); // Setup content observer for sticky button setupContentObserver(); } let openKiesWijzer = (e) => { e?.preventDefault(); startKeuzetool(); } const setKieswijzerPopup = (node) => { node.addEventListener('click', e => { e.preventDefault(); startKeuzetool(); }); node.classList.remove('openkeuzehulp'); } // observe, alle .openkeuzehulp buttons omzetten naar onclick openkieswijzer. Daarna openkeuzehulp class verwijderen, const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1 && node.classList.contains('openkeuzehulp')) { setKieswijzerPopup(node) } }); }); }); observer.observe(document.body, {childList: true, subtree: true}); document.querySelectorAll('.openkeuzehulp').forEach(node => setKieswijzerPopup(node)); if (window.location.search.includes('?keuzehulp')) { openKiesWijzer(); } // Keuzetool Product Functions - Part 2 // Product filtering, search, and cart functionality // Product filtering and search logic const baseUrl = 'https://www.radiator-outlet.nl/'; const category = 'collection'; let resultUrl = ''; let forcedWattage = false; let zoekWattage = 0; let maxForcedWattageTried = 0; // Filter mappings const manieren = {'elektrisch': 0.75, 'cv': 1, 'stadsverwarming': 1, 'warmtepomp': 1.4}; const kamers = { "badkamer": 829873, "woonkamer": 829871, "slaapkamer": 829872, "keuken": 829874, "kantoor": 829875, "gang": 829876 }; const filters = { breedte: { "823387": [30], "823388": [40], "823389": [45], "823390": [50], "823391": [60], "825019": [90], }, hoogte: { "823372": [50], "823373": [60], "823375": [70], "823376": [80], "823378": [100], "823379": [120], "823380": [140], "823381": [160], "825029": [170], "823382": [180], "823383": [200], }, watt: { "823421": [300, 400], "823418": [400, 500], "823419": [500, 600], "823420": [600, 700], "823422": [700, 800], "823423": [800, 900], "823424": [900, 1000], "823425": [1000, 1250], "823426": [1250, 1500], "823427": [1500, 2000], "823428": [2000, 2500], "823429": [2500, 3000], "823430": [3000, 3500], "823431": [3500, 4000], "823432": 4000 }, kleur: { "zwart": 824894, "wit": 824891, "antraciet": 824895, "chroom": 824892, "goud": 824893 }, variant: { "ribbel": 823691, "vlak": 823694, "groef": 823693 }, orientatie: { "verticaal": [823367, 829878], "horizontaal": 829877 }, aansluiting: { "zijkant": [823367, 823368], "rechtlinks-onder": [823367, 823368], "middenonder": 823368, "boven": [823367, 823368], "onder": [823367, 823368] } }; async function getProductHeight(product) { let specs = {}; try { const productUrl = baseUrl + "/" + currentLanguage + "/" + product.url + '?format=json'; const productResponse = await fetch(productUrl); const productData = await productResponse.json(); specs = productData.product.specs || {}; } catch (error) { console.error('Error fetching product details:', product.url, error); return ''; } console.log(specs) if (!specs || Object.values(specs).length === 0) { return ''; } // Find the spec with title "Hoogte" const heightSpec = Object.values(specs).find(spec => spec.title === 'Hoogte'); console.log(heightSpec) if (!heightSpec || !heightSpec.value) return ''; // Extract numeric value and remove " cm" suffix const heightValue = heightSpec.value.replace(/\s*cm\s*$/i, '').trim(); // Convert to number and return const numericHeight = parseInt(heightValue); return isNaN(numericHeight) ? '' : numericHeight.toString(); } function getNextWattageRange(currentWattage) { const numericCurrent = Math.round(parseFloat(currentWattage) || 0); if (numericCurrent <= 0) { forcedWattage = false; return false; } if (numericCurrent > maxForcedWattageTried) { maxForcedWattageTried = numericCurrent; } const wattageKeys = Object.keys(filters.watt).sort((a, b) => { const rangeA = Array.isArray(filters.watt[a]) ? filters.watt[a][0] : filters.watt[a]; const rangeB = Array.isArray(filters.watt[b]) ? filters.watt[b][0] : filters.watt[b]; return rangeA - rangeB; }); for (let i = 0; i < wattageKeys.length; i++) { const range = filters.watt[wattageKeys[i]]; if ( (Array.isArray(range) && numericCurrent >= range[0] && numericCurrent <= range[1]) || (!Array.isArray(range) && numericCurrent <= range) ) { const nextRange = filters.watt[wattageKeys[i + 1]]; if (!nextRange) { forcedWattage = false; return false; } const candidateWattage = Array.isArray(nextRange) ? nextRange[0] + 1 : nextRange + 1; if (candidateWattage <= numericCurrent || candidateWattage <= maxForcedWattageTried) { forcedWattage = false; return false; } forcedWattage = candidateWattage; maxForcedWattageTried = candidateWattage; return true; } } forcedWattage = false; return false; } function createProductSearchUrl() { const zoekfilters = []; // Get form data from current selections const formData = getCurrentFormData(); // Calculate wattage requirements const badkamer_toeslag = formData.room === 'badkamer' ? (formData.heating === 'warmtepomp' ? 1.25 : 0.75) : 1; const inhoud = (parseFloat(formData.height) || 0) / 100 * (parseFloat(formData.width) || 0) / 100 * (parseFloat(formData.length) || 0) / 100; const temperatuurverschil = parseFloat(formData.temperature) || 70; const isolatiefactor = 1 + (formData.isolation === 'slecht' ? 0.5 : formData.isolation === 'normaal' ? 0.25 : 0); const basis_warmtevraag = badkamer_toeslag * inhoud * temperatuurverschil * isolatiefactor; const vermogen_behouden = formData.keep_existing === 'yes' ? parseFloat(formData.radiator_power) || 0 : 0; const manieren_factor = manieren[formData.heating] || 1; const totaal_wattage = (basis_warmtevraag * manieren_factor) - vermogen_behouden; const radiatoren = parseInt(formData.radiator_count) || 1; const zoek_wattage = forcedWattage !== false ? forcedWattage : (totaal_wattage / radiatoren); const roundedZoekWattage = Math.round(zoek_wattage || 0); if (forcedWattage === false) { maxForcedWattageTried = roundedZoekWattage; } else { maxForcedWattageTried = Math.max(maxForcedWattageTried, roundedZoekWattage); } if (zoekWattage === 0) { zoekWattage = zoek_wattage; } console.log('Calculated wattage:', zoek_wattage, 'Total wattage:', totaal_wattage, 'Form data:', formData); // Add wattage filter for (const [key, range] of Object.entries(filters.watt)) { if (Array.isArray(range)) { if (zoek_wattage >= range[0] && zoek_wattage <= range[1]) { zoekfilters.push(key); break; } } else if (zoek_wattage >= range) { zoekfilters.push(key); break; } } // Add room filter if (formData.room && kamers[formData.room]) { zoekfilters.push(kamers[formData.room]); } // Add heating type filter if (formData.heating) { if (formData.heating === 'elektrisch') { zoekfilters.push(829883); } else { zoekfilters.push(913796); zoekfilters.push(829884); } } // Add color filter if (formData.radiator_color && filters.kleur[formData.radiator_color]) { zoekfilters.push(filters.kleur[formData.radiator_color]); } // Add orientation filter if (formData.radiator_orientation && filters.orientatie[formData.radiator_orientation]) { const orient = filters.orientatie[formData.radiator_orientation]; if (Array.isArray(orient)) { if(formData.heating === 'elektrisch') // remove value 823367 orient.splice(orient.indexOf(823367), 1); zoekfilters.push(...orient); } else { zoekfilters.push(orient); } } if (formData.radiator_orientation === undefined && formData.room === 'badkamer' && formData.heating !== 'elektrisch') { zoekfilters.push(823367); zoekfilters.push(824151); } // Add variant filter if (formData.radiator_variant && filters.variant[formData.radiator_variant]) { zoekfilters.push(filters.variant[formData.radiator_variant]); } // Add connection filter if (formData.radiator_connection && filters.aansluiting[formData.radiator_connection]) { const aansluitingFilter = filters.aansluiting[formData.radiator_connection]; if (Array.isArray(aansluitingFilter)) { zoekfilters.push(...aansluitingFilter); } else { zoekfilters.push(aansluitingFilter); } } // Add size filters based on allowed dimensions (not excluded ones) const excludedSizeCombinations = Array.from(document.querySelectorAll('input[name="excluded_sizes"]:checked')) .map(checkbox => checkbox.value); if (excludedSizeCombinations.length > 0) { // Get all available size combinations from the UI const allSizeCombinations = Array.from(document.querySelectorAll('input[name="excluded_sizes"]')) .map(checkbox => checkbox.value); // Calculate allowed (non-excluded) size combinations const allowedSizeCombinations = allSizeCombinations.filter( combination => !excludedSizeCombinations.includes(combination) ); // Convert allowed size combinations to filter IDs const allowedWidths = new Set(); const allowedHeights = new Set(); allowedSizeCombinations.forEach(combination => { const [width, height] = combination.split('x').map(Number); allowedWidths.add(width); allowedHeights.add(height); }); // Add filter IDs for allowed dimensions for (const [filterId, widthArray] of Object.entries(filters.breedte)) { if (allowedWidths.has(widthArray[0])) { zoekfilters.push(filterId); } } for (const [filterId, heightArray] of Object.entries(filters.hoogte)) { if (allowedHeights.has(heightArray[0])) { zoekfilters.push(filterId); } } } // Store excluded sizes for client-side filtering as backup window.excludedSizeCombinations = excludedSizeCombinations; // remove duplicates from zoekfilters const uniqueFilters = [...new Set(zoekfilters)]; // Generate the URL const url = `${baseUrl}${currentLanguage}/${category}/page1.json?` + uniqueFilters.map(filter => `filter[]=${filter}`).join('&') + '&limit=2000&mode=grid&sort=lowest'; console.log('Generated search URL:', url); resultUrl = url; return url; } function getCurrentFormData() { return { room: document.querySelector('input[name="room"]:checked')?.value, isolation: document.querySelector('input[name="isolation"]:checked')?.value, height: document.getElementById('height')?.value, width: document.getElementById('width')?.value, length: document.getElementById('length')?.value, heating: document.querySelector('input[name="heating"]:checked')?.value, keep_existing: document.querySelector('input[name="keep_existing"]:checked')?.value, radiator_power: document.getElementById('radiator_power')?.value, temperature: document.getElementById('desired_temperature')?.value, radiator_count: document.getElementById('radiator_count')?.value, radiator_color: document.querySelector('input[name="radiator_color"]:checked')?.value, radiator_orientation: document.querySelector('input[name="radiator_orientation"]:checked')?.value, radiator_variant: document.querySelector('input[name="radiator_variant"]:checked')?.value, radiator_connection: document.querySelector('input[name="radiator_connection"]:checked')?.value, aansluitset: document.querySelector('input[name="aansluitset"]:checked')?.value, leidingen: document.querySelector('input[name="leidingen"]:checked')?.value }; } async function fetchResultsAndUpdateUI(retries = 3) { if (!resultUrl || resultUrl === '') { createProductSearchUrl(); } try { console.log('Fetching results from:', resultUrl); const response = await fetch(resultUrl); const data = await response.json(); const count = data.count ?? 0; const products = data.products ?? {}; if (count === 0 && retries > 0) { console.log("No results found, trying next wattage range..."); const nextWattageRange = getNextWattageRange( forcedWattage !== false ? forcedWattage : zoekWattage ); if (nextWattageRange) { console.log(`Retrying with forced wattage: ${forcedWattage}`); createProductSearchUrl(); return fetchResultsAndUpdateUI(retries - 1); } else { // No wattage range found, show extra radiator question console.log("No suitable wattage range found, showing extra radiator question"); showExtraRadiatorStep(); return; } } let minPrice = Infinity; let maxPrice = -Infinity; Object.values(products).forEach(product => { const price = product.price?.price_incl ?? 0; if (price < minPrice) minPrice = price; if (price > maxPrice) maxPrice = price; }); minPrice = minPrice === Infinity ? 0 : minPrice; maxPrice = maxPrice === -Infinity ? 0 : maxPrice; // Show results in console for now - we'll implement UI display later console.log(`Results: ${count} products found, €${minPrice.toFixed(2)} - €${maxPrice.toFixed(2)}`); return { count, minPrice, maxPrice, products, url: resultUrl }; } catch (error) { console.error("Error fetching results:", error); return { count: 0, minPrice: 0, maxPrice: 0, products: {}, error: error.message }; } } // Global variables for price range let originalPriceRange = {min: 0, max: 3000}; // Product rendering functions async function fetchAndDisplayProducts(isInitialLoad = false) { if (!resultUrl || resultUrl === '') { createProductSearchUrl(); } const productsContainer = document.getElementById('productResults'); try { console.log('Fetching products from:', resultUrl); const response = await fetch(resultUrl); const data = await response.json(); const count = data.count ?? 0; const products = data.products ?? {}; // On initial load, determine price range and setup slider if (isInitialLoad && Object.keys(products).length > 0) { let minPrice = Infinity; let maxPrice = -Infinity; Object.values(products).forEach(product => { const price = product.price?.price_incl || product.price?.price || 0; if (price > 0) { if (price < minPrice) minPrice = price; if (price > maxPrice) maxPrice = price; } }); originalPriceRange.min = minPrice === Infinity ? 0 : Math.floor(minPrice); originalPriceRange.max = maxPrice === -Infinity ? 3000 : Math.ceil(maxPrice); // Initialize price slider with actual price range updatePriceSliderRange(originalPriceRange.min, originalPriceRange.max); } // Update the product count in the filter tab const allProductsTab = document.querySelector('[data-translate="all_products"]'); if (allProductsTab) { allProductsTab.textContent = allProductsTab.textContent.replace(/\(\d+\)/, `(${count})`); } // Update radiator count in step title const radiatorCountSpan = document.getElementById('radiator-count'); if (radiatorCountSpan) { if (currentLanguage === 'nl') { radiatorCountSpan.textContent = count > 0 ? `${count} ideale` : 'geen'; } else { radiatorCountSpan.textContent = count > 0 ? `${count} radiateurs idéaux` : 'aucun radiateur idéal'; } } if (count === 0) { if (isInitialLoad) { // Try next wattage range first const nextWattageRange = getNextWattageRange( forcedWattage !== false ? forcedWattage : zoekWattage ); if (nextWattageRange) { console.log("No results found, trying next wattage range...", zoekWattage, forcedWattage); createProductSearchUrl(); return fetchAndDisplayProducts(true); // Retry with new wattage } else { // No higher wattage range available, show extra radiator question console.log("No suitable wattage range found, showing extra radiator question"); showExtraRadiatorStep(); return; } } else { // Not initial load, just show no products message productsContainer.innerHTML = `

    Geen producten gevonden met de geselecteerde filters.

    Probeer andere filterinstellingen.

    `; updateTexts(); // Update translations for error message return; } } // Convert products object to array and apply size filtering let productArray = Object.values(products); // Apply size filtering if excludedSizeCombinations exist if (window.excludedSizeCombinations && window.excludedSizeCombinations.length > 0) { productArray = productArray.filter(product => { if (product.size && product.size.x && product.size.y) { const productSizeCombination = `${Math.round(product.size.x)}x${Math.round(product.size.y)}`; return !window.excludedSizeCombinations.includes(productSizeCombination); } return true; // Keep products without size info }); } // Find hybride products and prioritize the cheapest one const hybrideProducts = productArray.filter(product => product.title && product.title.toLowerCase().includes('hybride') ); if (hybrideProducts.length > 0) { // Find the cheapest hybride product let cheapestHybride = hybrideProducts[0]; let lowestPrice = cheapestHybride.price?.price_incl || cheapestHybride.price?.price || Infinity; hybrideProducts.forEach(product => { const price = product.price?.price_incl || product.price?.price || Infinity; if (price < lowestPrice) { lowestPrice = price; cheapestHybride = product; } }); // Mark the cheapest hybride product as recommended cheapestHybride.isRecommended = true; // Remove the cheapest hybride from its current position productArray = productArray.filter(product => product !== cheapestHybride); // Add it to the beginning of the array productArray.unshift(cheapestHybride); } productArray = productArray.slice(0, 10); // Limit to 10 products const productHTML = await Promise.all( productArray.map(async (product, idx) => await renderProductCard(product, idx === 0)) ) productsContainer.innerHTML = productHTML.join(''); // Update translations for newly injected content updateTexts(); // Add event listeners for product interactions addProductEventListeners(); const deliveryBar = document.querySelector('.delivery-bar'); if (deliveryBar) { deliveryBar.style.display = 'block'; } // Fetch stock information for each product productArray.forEach(product => { fetchProductStock(product); }); } catch (error) { console.error('Error fetching products:', error); productsContainer.innerHTML = `

    Er is een fout opgetreden bij het laden van de producten.

    `; updateTexts(); // Update translations for error message } } function updatePriceSliderRange(min, max) { const minRange = document.getElementById('price-min-range'); const maxRange = document.getElementById('price-max-range'); const minDisplay = document.getElementById('price-min-display'); const maxDisplay = document.getElementById('price-max-display'); const minValue = document.getElementById('price-min-value'); const maxValue = document.getElementById('price-max-value'); if (minRange && maxRange) { // Update slider attributes minRange.min = min; minRange.max = max; minRange.value = min; maxRange.min = min; maxRange.max = max; maxRange.value = max; // Update displays if (minDisplay) minDisplay.textContent = min; if (maxDisplay) maxDisplay.textContent = max; if (minValue) minValue.textContent = min; if (maxValue) maxValue.textContent = max; // Reset current filters currentFilters.minPrice = null; currentFilters.maxPrice = null; } } function generateStars(score) { const rating = Math.round(score * 5); let stars = ''; for (let i = 1; i <= 5; i++) { if (i <= rating) { stars += '★'; } else { stars += '☆'; } } return stars; } function generateProductSubtitle(product) { // Get user selections from global variables const formData = getCurrentFormData(); let radiatorType = 'Radiator'; // Determine radiator type based on user selections if (formData.heating === 'elektrisch') { radiatorType = 'Elektrische radiator'; } else if (formData.radiatorType === 'handdoek') { radiatorType = 'Handdoekradiator'; } else if (formData.radiatorType === 'paneelradiator') { radiatorType = 'Paneelradiator'; } let wattage = ''; const wattageMatch = product.title?.toLowerCase().match(/(\d{3,4})\s*watt/); const wattageMatch2 = product.title?.toLowerCase().match(/(\d{3,4})\s*w\s/); if (wattageMatch) { wattage = `${wattageMatch[1]} Watt`; }else if (wattageMatch2) { wattage = `${wattageMatch2[1]} Watt`; } return `${radiatorType} • ${wattage}`; } async function fetchProductStock(product) { try { const stockResponse = await fetch(`${baseUrl}${currentLanguage}/${product.url}?format=json`); const stockData = await stockResponse.json(); const stockContainer = document.getElementById(`stock-${product.id}`); if (!stockContainer) return; const stock = stockData.product.stock; const stockIcon = stockContainer.querySelector('.stock-icon'); const stockSpans = stockContainer.querySelectorAll('span'); // Update stock status if (stock.on_stock) { stockIcon.style.backgroundColor = '#22c55e'; stockSpans[0].textContent = translateText('in_stock'); stockSpans[1].textContent = translateText('order_before_3pm'); } else if (stock.available && stock.allow_outofstock_sale) { stockIcon.style.backgroundColor = '#f59e0b'; stockSpans[0].textContent = translateText('backorder'); stockSpans[1].textContent = stock.delivery?.title || translateText('delivery_info_follows'); } else { stockIcon.style.backgroundColor = '#ef4444'; stockSpans[0].textContent = translateText('not_available'); stockSpans[1].textContent = ''; } // Update review count const ratingContainer = document.getElementById(`rating-${product.id}`); if (ratingContainer && stockData.product.reviews) { const reviewCount = stockData.product.reviews.length; const currentRating = (product.score * 5).toFixed(1); ratingContainer.textContent = `${currentRating}/5 (${reviewCount})`; } } catch (error) { console.error('Error fetching stock for product', product.id, error); const stockContainer = document.getElementById(`stock-${product.id}`); if (stockContainer) { const stockSpans = stockContainer.querySelectorAll('span'); stockSpans[0].textContent = translateText('stock_unknown'); stockSpans[1].textContent = ''; } } } async function renderProductCard(product, first) { const isElectric = getCurrentFormData().heating === 'elektrisch'; const electricBadge = isElectric ? '
    ELEKTRISCH
    ' : ''; // Determine if this product should show recommended badge const isRecommended = first || product.isRecommended; const recommendedBadge = isRecommended ? '
    #1 AANBEVOLEN
    ' : ''; // Calculate savings (example: random between 15-35%) const originalPrice = product.price.price_old ? parseFloat(product.price.price_old) : 199.95; const currentPrice = product.price ? parseFloat(product.price.price) : 159.95; const discount = Math.floor((originalPrice - currentPrice) / originalPrice * 100); const productFeatures = isElectric ? [translateText('fast_heating'), translateText('energy_efficient')] : [translateText('thermostat_control'), translateText('timer_function')]; const prodHeight = await getProductHeight(product); return `
    ${recommendedBadge} ${electricBadge}
    ${product.title}
    ${generateStars(product.score || 0)}
    ${(product.score * 5).toFixed(1)}/5
    ${product.brand?.title || 'OPPIO'}
    ${product.title || '80x50 cm - Oppio E-Basis Mat Zwart'}
    ${generateProductSubtitle(product)}
    ${productFeatures.map(feature => `
    ${feature}
    `).join('')}
    Laden...
    €${currentPrice.toFixed(2)}
    ${originalPrice > currentPrice ? `
    €${originalPrice.toFixed(2)}
    ` : ''}
    ${originalPrice > currentPrice ? `
    ${translateText('save_amount').replace('{amount}', (originalPrice - currentPrice).toFixed(2)).replace('{discount}', discount)}
    ` : ''}
    Snelle levering
    14 dagen bedenktijd
    ${first ? `` : ``}
    `; } function addProductEventListeners() { // Add any additional event listeners for product interactions console.log('Product event listeners added'); } // Global selection state let selectedRadiators = []; let selectedRadiatorHeights = []; let requiredRadiatorCount = 0; let selectedAansluitsets = []; let requiredAansluitsetCount = 0; async function selectProduct(productId) { console.log('Product selected:', productId); // Get required radiator count from form data const formData = getCurrentFormData(); requiredRadiatorCount = parseInt(formData.radiator_count) || 1; // Allow multiple selections of the same product if (selectedRadiators.length < requiredRadiatorCount) { // Find the button that was clicked const button = document.querySelector(`button[onclick="selectProduct('${productId}')"]`); if (button) { // Store original button content const originalContent = button.innerHTML; const originalClass = button.className; // Add to cart first try { await addProductToCart(button); // Change to "Toegevoegd" state only if cart addition was successful button.innerHTML = translateText('added_to_cart'); button.className = 'btn-added'; button.disabled = true; // Revert after 2.5 seconds setTimeout(() => { button.innerHTML = originalContent; button.className = originalClass; button.disabled = false; // Allow re-selection button.style.opacity = '1'; }, 2500); selectedRadiators.push(productId); const height = button.getAttribute('data-height'); if (height && !selectedRadiatorHeights.includes(height)) { selectedRadiatorHeights.push(height); } updateSelectionFooter(); // Check if we need connection sets if (selectedRadiators.length >= requiredRadiatorCount) { setTimeout(() => { checkForConnectionSets(); }, 3000); // Increased to allow button animation to complete } } catch (error) { console.error('Failed to add to cart:', error); // Show error state button.innerHTML = '❌ Fout'; button.className = 'btn-error'; setTimeout(() => { button.innerHTML = originalContent; button.className = originalClass; button.disabled = false; }, 2000); } } } else { console.log('Maximum number of radiators already selected'); // Optionally show a message that max is reached checkForConnectionSets(); } } async function addProductToCart(button, qty) { const pid = button.getAttribute('data-vid'); const title = button.getAttribute('data-title'); const cartUrl = button.getAttribute('data-cart-url'); console.log('Adding to cart:', title); // Create form data for cart addition const formData = { 'quantity': qty || '1', } // Prepare cart URL (convert product URL to cart URL) const baseUrl = 'https://www.radiator-outlet.nl'; const cartAddUrl = `${baseUrl}/${currentLanguage}/cart/add/${pid}/`; try { const response = await fetch(cartAddUrl, { method: 'POST', body: new URLSearchParams(formData), credentials: 'same-origin' }); if (!response.ok) { throw new Error(`Cart addition failed: ${response.status}`); } const result = await response.text(); console.log('Product added to cart successfully:', title); // Update cart UI if elements exist updateCartUI(); return result; } catch (error) { console.error('Error adding to cart:', error); throw error; } } function updateCartUI() { // Update cart quantity if element exists const cartQty = document.querySelector('#qty, .cart-qty'); if (cartQty) { // This would need to be updated based on actual cart response // For now, just increment by 1 const currentQty = parseInt(cartQty.textContent) || 0; cartQty.textContent = currentQty + 1; } console.log('Cart UI updated'); } function updateSelectionFooter() { let footerElement = document.querySelector('.radiator-selection-footer'); if (!footerElement) { createSelectionFooter(); footerElement = document.querySelector('.radiator-selection-footer'); } const radiatorRemaining = requiredRadiatorCount - selectedRadiators.length; const aansluitsetRemaining = requiredAansluitsetCount - selectedAansluitsets.length; const totalRemaining = radiatorRemaining + aansluitsetRemaining; const footerText = footerElement.querySelector('.selection-text'); const continueBtn = footerElement.querySelector('.continue-btn'); if (totalRemaining > 0) { let text = ''; if (radiatorRemaining > 0) { text += translateText('select_more_radiators').replace('{count}', radiatorRemaining).replace('{plural}', radiatorRemaining > 1 ? translateText('plural_radiator') : ''); } if (aansluitsetRemaining > 0) { if (text) text += ` ${translateText('and')} `; text += translateText('select_more_aansluitsets').replace('{count}', aansluitsetRemaining).replace('{plural}', aansluitsetRemaining > 1 ? translateText('plural_aansluitset') : ''); } footerText.textContent = text; continueBtn.style.display = 'none'; } else { let text = ''; if (requiredRadiatorCount > 0) { text += translateText('radiators_selected').replace('{count}', requiredRadiatorCount).replace('{plural}', requiredRadiatorCount > 1 ? translateText('plural_radiator') : ''); } if (requiredAansluitsetCount > 0) { if (text) text += ` ${translateText('and')} `; text += translateText('aansluitsets_selected').replace('{count}', requiredAansluitsetCount).replace('{plural}', requiredAansluitsetCount > 1 ? translateText('plural_aansluitset') : ''); } footerText.textContent = text; continueBtn.style.display = 'block'; } footerElement.style.display = 'block'; } function createSelectionFooter() { // Remove existing footer if it exists const existingFooter = document.querySelector('.radiator-selection-footer'); if (existingFooter) { existingFooter.remove(); } const footer = document.createElement('div'); footer.className = 'radiator-selection-footer'; footer.innerHTML = `
    ${translateText('select_radiators').replace('{count}', requiredRadiatorCount).replace('{plural}', requiredRadiatorCount > 1 ? translateText('plural_radiator') : '')}
    `; // Insert footer as first child in delivery-bar (before delivery-bar-content) const deliveryBar = document.querySelector('.delivery-bar'); const deliveryBarContent = document.querySelector('.delivery-bar-content'); if (deliveryBar && deliveryBarContent) { deliveryBar.insertBefore(footer, deliveryBarContent); } else if (deliveryBar) { deliveryBar.insertBefore(footer, deliveryBar.firstChild); } else { document.body.appendChild(footer); } // Show footer immediately footer.style.display = 'block'; } function checkForConnectionSets() { const formData = getCurrentFormData(); const deliveryBar = document.querySelector('.delivery-bar'); if (deliveryBar) { deliveryBar.style.display = 'none'; } // Check if connection sets are needed (non-electric heating and aansluitset step was answered with "ja") if (formData.heating !== 'elektrisch') { // && formData.aansluitset === 'ja' // Show aansluitset selection step showStep('step13'); } else { // Go to final checkout/confirmation showFinalStep(); } } async function loadAansluitsetProducts() { const formData = getCurrentFormData(); const connection = formData.radiator_connection; const leidingen = formData.leidingen; const productsSection = document.getElementById('aansluitset-products'); productsSection.style.display = 'block'; console.log('Loading aansluitset products for connection:', connection, 'leidingen:', leidingen); // Filter products based on connection type and pipe situation const matchingUrls = []; for (const [url, rules] of Object.entries(aansluitsetProducts)) { let matches = true; // Check leidingen rule if (Array.isArray(rules.kw__leidingen)) matches = rules.kw__leidingen.includes(leidingen) else if (rules.kw__leidingen && rules.kw__leidingen !== leidingen) matches = false; // Check aansluiting rule if it exists if (matches && rules.kw__aansluiting) { if (rules.kw__aansluiting[0] === 'not') { // If rule is ['not', 'middenonder', 'rechtlinks-onder'], connection should NOT be in the rest of the array const excludedConnections = rules.kw__aansluiting.slice(1); if (excludedConnections.includes(connection)) { matches = false; } } else { // If rule is ['middenonder', 'rechtlinks-onder'], connection should be in the array if (!rules.kw__aansluiting.includes(connection)) { matches = false; } } } if (matches) { matchingUrls.push(url); } } console.log('Matching aansluitset URLs:', matchingUrls); // Fetch and render products const resultsContainer = document.getElementById('aansluitsetResults'); if (resultsContainer) { try { let validProducts = []; if (matchingUrls.length > 0) { // Fetch all products in parallel const productPromises = matchingUrls.map(url => fetchAansluitsetProduct(url)); const products = await Promise.all(productPromises); // Filter out failed fetches validProducts = products.filter(product => product !== null); } // Always add hardcoded product to the list //validProducts.push(hardcodedProduct); // Update product count const countSpan = document.getElementById('aansluitset-count'); if (countSpan) { countSpan.textContent = validProducts.length; } const productHTML = validProducts.map(product => renderAansluitsetCard(product)).join(''); resultsContainer.innerHTML = productHTML; // Fetch stock information for each product (skip hardcoded product) validProducts.forEach(product => { if (product.id !== '134802320') { fetchAansluitsetStock(product); } }); } catch (error) { console.error('Error loading aansluitset products:', error); resultsContainer.innerHTML = `

    ${translateText('error_loading_aansluitsets')}

    `; } } } // Load ECA Insert product for step 14 async function loadInsertProduct() { console.log('Loading ECA Insert product'); const resultsContainer = document.getElementById('insertProductResults'); if (!resultsContainer) return; // Show loading state resultsContainer.innerHTML = '

    Product laden...

    '; try { const insertProduct = await fetchInsertProduct('https://www.radiator-outlet.nl/nl/eca-insert-voor-8-radiatoren.html'); if (insertProduct) { const productHTML = renderInsertCard(insertProduct); resultsContainer.innerHTML = productHTML; // Fetch stock information fetchInsertStock(insertProduct); } else { resultsContainer.innerHTML = `

    ${translateText('error_loading_insert')}

    `; } } catch (error) { console.error('Error loading insert product:', error); resultsContainer.innerHTML = `

    ${translateText('error_loading_insert')}

    `; } } async function fetchInsertProduct(url) { try { const response = await fetch(`${url}?format=json`); const data = await response.json(); if (data.product) { return { id: data.product.id, vid: data.product.vid, title: data.product.title, subtitle: 'ECA Insert voor 8 radiatoren', price: data.product.price?.price_incl || data.product.price?.price || 0, image: data.product.thumb || data.product.image, url: url, stock: data.product.stock, brand: data.product.brand, score: data.product.score || 0.9 }; } return null; } catch (error) { console.error('Error fetching insert product from', url, error); return null; } } function renderInsertCard(product) { const currentPrice = parseFloat(product.price) || 0; const originalPrice = product.price_old ? parseFloat(product.price_old) : currentPrice; const stars = generateStars(product.score || 0.9); return `
    ${translateText('recommended')}
    ${product.title}
    ${stars}
    ${(product.score * 5).toFixed(1)}/5
    ${product.brand?.title || 'ECA'}
    ${product.title}
    ${product.subtitle}
    Laden...
    €${currentPrice.toFixed(2)}
    ${originalPrice > currentPrice ? `
    €${originalPrice.toFixed(2)}
    ` : ''}
    ${originalPrice > currentPrice ? `
    ${translateText('save_amount_simple').replace('{amount}', (originalPrice - currentPrice).toFixed(2))}
    ` : ''}
    ${translateText('free_shipping_text')}
    ${translateText('return_policy')}
    `; } async function fetchInsertStock(product) { try { const stockContainer = document.getElementById(`insert-stock-${product.id}`); if (!stockContainer) return; const stock = product.stock; const stockIcon = stockContainer.querySelector('.stock-icon'); const stockSpans = stockContainer.querySelectorAll('span'); // Update stock status if (stock && stock.on_stock) { stockIcon.style.backgroundColor = '#22c55e'; stockIcon.textContent = '✓'; if (stockSpans[0]) stockSpans[0].textContent = translateText('in_stock'); if (stockSpans[1]) stockSpans[1].textContent = translateText('order_before_3pm'); } else if (stock && stock.available && stock.allow_outofstock_sale) { stockIcon.style.backgroundColor = '#f59e0b'; stockIcon.textContent = '!'; if (stockSpans[0]) stockSpans[0].textContent = translateText('backorder'); if (stockSpans[1]) stockSpans[1].textContent = stock.delivery?.title || translateText('delivery_info_follows'); } else { stockIcon.style.backgroundColor = '#ef4444'; stockIcon.textContent = '✗'; if (stockSpans[0]) stockSpans[0].textContent = translateText('not_available'); if (stockSpans[1]) stockSpans[1].textContent = ''; } } catch (error) { console.error('Error updating stock for insert product', product.id, error); } } function selectInsertProduct(productId) { console.log('Selecting insert product:', productId); const button = document.querySelector(`button[onclick*="selectInsertProduct('${productId}'"]`); if (button) { // Show loading state const originalContent = button.innerHTML; button.innerHTML = translateText('loading_btn'); button.disabled = true; // Add to cart const qty = requiredRadiatorCount; // Add 2 if more than 4 radiators addProductToCart(button, qty); setTimeout(() => { button.innerHTML = translateText('added_to_cart'); button.className = 'btn-added'; setTimeout(() => { console.log('Insert product selected, continuing to next step'); // Continue to next step after selection nextStep(); }, 1500); }, 1000); } } async function fetchAansluitsetProduct(url) { try { const response = await fetch(`${url.replaceAll('#', '')}?format=json`); const data = await response.json(); if (data.product) { return { id: data.product.id, vid: data.product.vid, title: data.product.title, subtitle: data.product.brand?.title || 'Thermostatische onderdelen', price: data.product.price?.price_incl || data.product.price?.price || 0, image: data.product.thumb || data.product.image, url: url, stock: data.product.stock, brand: data.product.brand, score: data.product.score || 0.9 }; } return null; } catch (error) { console.error('Error fetching aansluitset product from', url, error); return null; } } async function fetchAansluitsetStock(product) { // Use the same logic as fetchProductStock but for aansluitset products try { const stockContainer = document.getElementById(`aansluitset-stock-${product.id}`); if (!stockContainer) return; const stock = product.stock; const stockIcon = stockContainer.querySelector('.stock-icon'); const stockSpans = stockContainer.querySelectorAll('span'); // Update stock status if (stock && stock.on_stock) { stockIcon.style.backgroundColor = '#22c55e'; stockIcon.textContent = '✓'; if (stockSpans[0]) stockSpans[0].textContent = translateText('in_stock'); if (stockSpans[1]) stockSpans[1].textContent = translateText('order_before_3pm'); } else if (stock && stock.available && stock.allow_outofstock_sale) { stockIcon.style.backgroundColor = '#f59e0b'; stockIcon.textContent = '!'; if (stockSpans[0]) stockSpans[0].textContent = translateText('backorder'); if (stockSpans[1]) stockSpans[1].textContent = stock.delivery?.title || translateText('delivery_info_follows'); } else { stockIcon.style.backgroundColor = '#ef4444'; stockIcon.textContent = '✗'; if (stockSpans[0]) stockSpans[0].textContent = translateText('not_available'); if (stockSpans[1]) stockSpans[1].textContent = ''; } } catch (error) { console.error('Error updating stock for aansluitset product', product.id, error); } } function renderAansluitsetCard(product) { const currentPrice = parseFloat(product.price) || 0; const originalPrice = product.price_old ? parseFloat(product.price_old) : currentPrice; const stars = generateStars(product.score || 0.9); return `
    ${translateText('popular_choice')}
    ${product.title}
    ${stars}
    ${(product.score * 5).toFixed(1)}/5
    ${product.brand?.title || 'OPPIO'}
    ${product.title}
    ${product.subtitle}
    Laden...
    €${currentPrice.toFixed(2)}
    ${originalPrice > currentPrice ? `
    €${originalPrice.toFixed(2)}
    ` : ''}
    ${originalPrice > currentPrice ? `
    ${translateText('save_amount_simple').replace('{amount}', (originalPrice - currentPrice).toFixed(2))}
    ` : ''}
    ${translateText('free_shipping_text')}
    ${translateText('return_policy')}
    `; } function selectAansluitset(productId, quantity) { console.log(`Selecting ${quantity} of aansluitset:`, productId); // Set required aansluitset count if not set yet if (requiredAansluitsetCount === 0) { requiredAansluitsetCount = 1; // Typically 1 aansluitset is needed } const button = document.querySelector(`button[onclick*="selectAansluitset('${productId}'"]`); if (button) { // Check if selected product is an onderblokset const productTitle = button.getAttribute('data-title'); if (productTitle && productTitle.toLowerCase().includes('onderblokset')) { console.log('Onderblokset selected - setting flag for step 14'); window.isOnderbloksetSelected = true; } // Show loading state const originalContent = button.innerHTML; button.innerHTML = translateText('loading_btn'); button.disabled = true; const qty = requiredRadiatorCount; addProductToCart(button, qty); // Simulate adding to cart (you can replace this with actual cart logic) setTimeout(() => { button.innerHTML = translateText('quantity_added').replace('{quantity}', quantity); button.className = 'btn-added'; // Add to selected aansluitsets and update footer selectedAansluitsets.push(productId); updateSelectionFooter(); setTimeout(() => { const formData = getCurrentFormData(); // Navigate based on whether onderblokset was selected if (window.isOnderbloksetSelected && formData.room !== 'badkamer') { console.log('Onderblokset selected, going to step 14'); showStep('step14'); } else { console.log('Regular aansluitset selected, going to step 19'); showStep('step19'); } }, 1500); }, 1000); } } function showFinalStep() { // Hide selection footer const footer = document.querySelector('.radiator-selection-footer'); if (footer) footer.style.display = 'none'; // Navigate to step 19 (stromingsbuis step is already handled in checkForConnectionSets) showStep('step19'); } window.addEventListener('message', function (event) { if (event.data.action === 'setLanguage') { currentLanguage = event.data.language; document.getElementById('languageSelect').value = currentLanguage; updateTexts(); } }); // Dual Range Slider Functionality function initializePriceSlider() { const minRange = document.getElementById('price-min-range'); const maxRange = document.getElementById('price-max-range'); const minDisplay = document.getElementById('price-min-display'); const maxDisplay = document.getElementById('price-max-display'); const minValue = document.getElementById('price-min-value'); const maxValue = document.getElementById('price-max-value'); function updateSlider() { let minVal = parseInt(minRange.value); let maxVal = parseInt(maxRange.value); const min = parseInt(minRange.min); const max = parseInt(minRange.max); // Prevent min from going above max if (minVal > maxVal - 10) { minVal = maxVal - 10; minRange.value = minVal; } // Prevent max from going below min if (maxVal < minVal + 10) { maxVal = minVal + 10; maxRange.value = maxVal; } // Calculate percentages for gradients const minPercent = ((minVal - min) / (max - min)) * 100; const maxPercent = ((maxVal - min) / (max - min)) * 100; // Update gradients minRange.style.background = `linear-gradient(to right, #ddd 0%, #ddd ${minPercent}%, #33333300 ${minPercent}%, #33333300 100%)`; maxRange.style.background = `linear-gradient(to right, #33333300 0%, #33333300 ${maxPercent}%, #ddd ${maxPercent}%, #ddd 100%)`; // Update displays minDisplay.textContent = minVal; maxDisplay.textContent = maxVal; minValue.textContent = minVal; maxValue.textContent = maxVal; } function applyPriceFilter() { const minVal = parseInt(minRange.value); const maxVal = parseInt(maxRange.value); // Apply price filter and reload products filterAndReloadProducts({ minPrice: minVal, maxPrice: maxVal }); } minRange.addEventListener('input', updateSlider); maxRange.addEventListener('input', updateSlider); // Add price filter on change (with debounce) let priceFilterTimeout; minRange.addEventListener('change', () => { clearTimeout(priceFilterTimeout); priceFilterTimeout = setTimeout(applyPriceFilter, 500); }); maxRange.addEventListener('change', () => { clearTimeout(priceFilterTimeout); priceFilterTimeout = setTimeout(applyPriceFilter, 500); }); // Initialize updateSlider(); } // Global filter state let currentFilters = { sortBy: 'lowest', // lowest, highest, best_selling, most_popular minPrice: null, maxPrice: null }; function filterAndReloadProducts(filters = {}) { // Update current filters currentFilters = {...currentFilters, ...filters}; // Create new URL with filters applied let filterUrl = resultUrl; // Apply sorting if (currentFilters.sortBy === 'highest') { filterUrl = filterUrl.replace('sort=lowest', 'sort=highest'); } else if (currentFilters.sortBy === 'best_selling') { filterUrl = filterUrl.replace('sort=lowest', 'sort=bestsellers'); } else if (currentFilters.sortBy === 'most_popular') { filterUrl = filterUrl.replace('sort=lowest', 'sort=popular'); } else { filterUrl = filterUrl.replace(/sort=(highest|bestsellers|popular)/, 'sort=lowest'); } filterUrl = filterUrl.replace(/[&?]min=\d+/g, '').replace(/[&?]max=\d+/g, ''); // Add new price parameters if specified if (currentFilters.minPrice !== null && currentFilters.minPrice > 0) { filterUrl += `&min=${currentFilters.minPrice}`; } if (currentFilters.maxPrice !== null && currentFilters.maxPrice < 10000) { filterUrl += `&max=${currentFilters.maxPrice}`; } console.log('Filtering products with:', currentFilters, 'URL:', filterUrl); // Update resultUrl and reload products resultUrl = filterUrl; fetchAndDisplayProducts(); } function initializeFilterTabs() { const filterTabs = document.querySelectorAll('.filter-tab'); filterTabs.forEach(tab => { tab.addEventListener('click', function () { filterTabs.forEach(t => t.classList.remove('active')); this.classList.add('active'); // Determine sort type based on tab content const tabText = this.textContent.toLowerCase(); let sortBy = 'lowest'; if (tabText.includes('hoogste') || tabText.includes('highest')) { sortBy = 'highest'; } else if (tabText.includes('verkocht') || tabText.includes('best selling')) { sortBy = 'best_selling'; } else if (tabText.includes('keuze') || tabText.includes('choice')) { sortBy = 'most_popular'; } filterAndReloadProducts({sortBy}); }); }); } function showExtraRadiatorStep() { showStep('step17'); setTimeout(() => { const requiredWattage = Math.round(zoekWattage); const subtitleElement = document.querySelector('[data-translate="extra_radiator_subtitle"]'); if (subtitleElement) { const translatedText = translations[currentLanguage].extra_radiator_subtitle; subtitleElement.textContent = translatedText.replace('{wattage}', requiredWattage.toString()); } }, 50); } function handleExtraRadiatorResponse() { const extraRadiatorChoice = document.querySelector('input[name="extra_radiator"]:checked'); if (extraRadiatorChoice && extraRadiatorChoice.value === 'yes') { const formData = getCurrentFormData(); const currentCount = parseInt(formData.radiator_count) || 1; const newCount = currentCount + 1; const radiatorCountInput = document.getElementById('radiator_count'); if (radiatorCountInput) { radiatorCountInput.value = newCount; } console.log(`Increasing radiator count from ${currentCount} to ${newCount}`); zoekWattage = 0; forcedWattage = false; maxForcedWattageTried = 0; createProductSearchUrl(); showStep('step16'); } else if (extraRadiatorChoice && extraRadiatorChoice.value === 'no') { showStep('step16'); setTimeout(() => { fetchAndDisplayProducts(false); }, 100); } } async function loadStromingsbuisProducts() { const container = document.getElementById('stromingsbuisResults'); if (!container) return; container.innerHTML = `
    ${translateText('loading_stromingsbuis')}
    `; try { const maxHeight = getSelectedRadiatorMaxHeight(); const stromingsbuisUrl = getStromingsbuisUrl(maxHeight); if (!stromingsbuisUrl) { container.innerHTML = `
    ${translateText('no_suitable_stromingsbuis')}
    `; return; } const response = await fetch(stromingsbuisUrl + '?format=json'); const productData = await response.json(); if (productData && productData.product) { displayStromingsbuisProduct(productData.product, container); } else { container.innerHTML = `
    ${translateText('error_loading_stromingsbuis')}
    `; } } catch (error) { console.error('Error loading stromingsbuis:', error); container.innerHTML = `
    ${translateText('error_loading_stromingsbuis')}
    `; } } function getSelectedRadiatorMaxHeight() { let maxHeight = 0; selectedRadiatorHeights.forEach(height => { const numericHeight = parseInt(height); if (!isNaN(numericHeight) && numericHeight > maxHeight) { maxHeight = numericHeight; } }); console.log('Max radiator height:', maxHeight); return maxHeight; } function getStromingsbuisUrl(height) { if (height >= 180) { return 'https://www.radiator-outlet.nl/nl/stromingsbuis-1740-x-1-2.html'; } else if (height >= 111) { return 'https://www.radiator-outlet.nl/nl/stromingsbuis-1110-x-1-2.html'; } else if (height >= 80) { return 'https://www.radiator-outlet.nl/nl/stromingsbuis-720-x-1-2.html'; } else { return 'https://www.radiator-outlet.nl/nl/stromingsbuis-720-x-1-2.html'; } } function displayStromingsbuisProduct(product, container) { const productHTML = `
    ${product.title}

    ${product.title}

    €${product.price.price} ${product.price.price_old ? `€${product.price.price_old}` : ''}
    `; container.innerHTML = productHTML; } function selectStromingsbuis(productId) { console.log('Stromingsbuis selected:', productId); const productItem = document.querySelector('.stromingsbuis-product'); if (productItem) { productItem.classList.add('selected'); const button = productItem.querySelector('button'); if (button) { addProductToCart(button, requiredRadiatorCount); } } } document.addEventListener('DOMContentLoaded', function () { initializePriceSlider(); initializeFilterTabs(); });