Configurator met meerprijs Nieuw
Productconfigurator voor een dakkapel: breedte, kozijn en glas als keuzerijen met de meerprijs per optie, extra's als vinkjes, en een samenvatting met elke gekozen meerprijs en een totaal incl. btw dat naar het nieuwe bedrag telt. Echte radioknoppen en checkboxes in fieldsets (pijltjes en Spatie werken), :has(:checked) voor de gekozen staat met JS-klasse als fallback, aria-live op het totaal. Na "Offerte aanvragen" laad- en successtaat. Prijzen zijn voorbeeldbedragen.
Zo gebruik je het
- Plak de HTML op de plek waar het onderdeel moet komen.
- Zet de CSS in je stylesheet. Alle klassen hebben een eigen voorvoegsel, dus niets botst met je eigen opmaak.
- Voeg de JavaScript toe en roep init() aan met het element waar de HTML in staat.
<!-- Configurator met meerprijs · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="bcm-q"><form class="bcm" novalidate><div class="bcm__opts"><p class="bcm__h">Stel je dakkapel samen</p></div><div class="bcm__side"><p class="bcm__k">Jouw dakkapel</p><ul class="bcm__lines"></ul><p class="bcm__tot"><span>Totaal incl. 21% btw</span><b class="bcm__t" aria-live="polite"></b></p><p class="bcm__inc">Incl. montage in 1 dag en steiger</p><button type="submit" class="bcm__go">Offerte aanvragen</button><p class="bcm__st" role="status"></p></div></form></div>
</div>/* Configurator met meerprijs · NedDev · eigen werk. */
.bcm-q{position:absolute;inset:0;container-type:inline-size}
.bcm{position:absolute;inset:0;margin:0;display:grid;grid-template-columns:minmax(0,1fr) 150px;background:#fff;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;overflow:hidden}
.bcm__opts{padding:10px 12px;overflow:auto;overscroll-behavior:contain}
.bcm__h{margin:0 0 6px;font-size:14px;font-weight:700}
.bcm__fs{margin:0 0 8px;padding:0;border:0;min-width:0}
.bcm__fs legend{padding:0;margin-bottom:4px;font:500 9.5px 'JetBrains Mono',monospace;text-transform:uppercase;letter-spacing:.07em;color:#5c5a56}
.bcm__seg{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px}
.bcm__o{position:relative;display:block;cursor:pointer}
.bcm__o input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}
.bcm__o span{display:block;padding:4px 6px;border:1px solid rgba(10,10,10,.2);border-radius:4px;font-size:12px;font-weight:600;line-height:1.2;transition:border-color .15s,background-color .15s,box-shadow .15s}
.bcm__o small{display:block;font-size:10px;font-weight:500;color:#5c5a56;font-variant-numeric:tabular-nums}
.bcm__o:hover span{border-color:#0a0a0a}
.bcm__o input:focus-visible+span{outline:2px solid #0a0a0a;outline-offset:2px}
.bcm__o input:checked+span,.bcm__o.is-on span{border-color:#0a0a0a;box-shadow:inset 0 0 0 1px #0a0a0a;background:#fbfaf8}
.bcm__o input:checked+span small,.bcm__o.is-on span small{color:#0a0a0a}
.bcm__x{display:grid;gap:3px}
.bcm__c{display:flex;align-items:center;gap:7px;padding:3px 0;font-size:12px;cursor:pointer}
.bcm__c input{width:14px;height:14px;margin:0;accent-color:#0a0a0a;cursor:pointer}
.bcm__c input:focus-visible{outline:2px solid #0a0a0a;outline-offset:2px}
.bcm__c em{margin-left:auto;font-style:normal;font-size:11px;color:#5c5a56;font-variant-numeric:tabular-nums}
.bcm__side{display:flex;flex-direction:column;padding:10px 12px;background:#0a0a0a;color:#fff;min-height:0;overflow:auto}
.bcm__k{margin:0 0 6px;font:500 9.5px 'JetBrains Mono',monospace;text-transform:uppercase;letter-spacing:.07em;color:#bdbab4}
.bcm__lines{margin:0;padding:0;list-style:none;font-size:11px;line-height:1.3}
.bcm__lines li{display:flex;justify-content:space-between;gap:6px;padding:2px 0;color:#d9d6d0}
.bcm__lines li b{font-weight:500;color:#fff;font-variant-numeric:tabular-nums;white-space:nowrap}
.bcm__lines li.is-new{animation:bcm-in .35s ease}
@keyframes bcm-in{from{background:rgba(245,72,15,.35)}}
.bcm__tot{margin:8px 0 0;padding-top:7px;border-top:1px solid rgba(255,255,255,.2)}
.bcm__tot span{display:block;font-size:10px;color:#bdbab4}
.bcm__tot b{font-size:19px;font-weight:700;font-variant-numeric:tabular-nums}
.bcm__inc{margin:2px 0 8px;font-size:10px;color:#bdbab4}
.bcm__go{margin-top:auto;height:32px;border:0;border-radius:4px;background:#F5480F;color:#0a0a0a;font:700 12px 'Switzer',system-ui,sans-serif;cursor:pointer;transition:background-color .15s,color .15s}
.bcm__go:hover:not(:disabled){background:#fff}
.bcm__go:active:not(:disabled){transform:translateY(1px)}
.bcm__go:focus-visible{outline:2px solid #fff;outline-offset:2px}
.bcm__go:disabled{opacity:.7;cursor:progress}
.bcm__st{margin:5px 0 0;font-size:10.5px;line-height:1.3;color:#9fd8b1}
.bcm__st:empty{display:none}
@container (max-width:380px){.bcm{grid-template-columns:1fr;grid-template-rows:minmax(0,1fr) auto}.bcm__side{display:grid;grid-template-columns:1fr auto;align-items:center;gap:2px 10px;padding:8px 12px}.bcm__k,.bcm__lines,.bcm__inc{display:none}.bcm__tot{margin:0;padding:0;border:0}.bcm__go{margin:0;padding:0 12px}.bcm__st{grid-column:1/-1}}
@media (prefers-reduced-motion:reduce){.bcm *{transition:none!important;animation:none!important}}// Configurator met meerprijs · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var f=root.querySelector('.bcm');if(!f)return;
var opts=f.querySelector('.bcm__opts'),lines=f.querySelector('.bcm__lines'),tEl=f.querySelector('.bcm__t'),go=f.querySelector('.bcm__go'),st=f.querySelector('.bcm__st');
/* voorbeeldprijzen incl. btw */
var BASE=7950,G=[
{k:'br',t:'Breedte',o:[['2 m','',0],['3 m','',1500],['4 m','',3150]]},
{k:'kz',t:'Kozijn',o:[['Wit','kunststof',0],['Antraciet','kunststof',450],['Hout','meranti',1250]]},
{k:'gl',t:'Glas',o:[['HR++','',0],['Triple','',690],['Zonwerend','',380]]}],
X=[['rl','Rolluiken, elektrisch',1190],['hr','Horren',180],['vr','Ventilatieroosters',95]];
var shown=0,raf=0,prev={};
function eur(n){return '€ '+Math.round(n).toLocaleString('nl-NL')}
function plus(n){return n?'+'+eur(n):'inbegrepen'}
opts.insertAdjacentHTML('beforeend',G.map(function(g){return '<fieldset class="bcm__fs"><legend>'+g.t+'</legend><div class="bcm__seg">'+g.o.map(function(o,i){return '<label class="bcm__o"><input type="radio" name="bcm-'+g.k+'" value="'+i+'"'+(i===(g.k==='br'?1:0)?' checked':'')+' aria-label="'+o[0]+(o[1]?' '+o[1]:'')+', '+plus(o[2])+'"><span>'+o[0]+'<small>'+plus(o[2])+'</small></span></label>'}).join('')+'</div></fieldset>'}).join('')+
'<fieldset class="bcm__fs"><legend>Extra</legend><div class="bcm__x">'+X.map(function(x,i){return '<label class="bcm__c"><input type="checkbox" name="bcm-'+x[0]+'"'+(i===0?' checked':'')+'>'+x[1]+'<em>+'+eur(x[2])+'</em></label>'}).join('')+'</div></fieldset>');
function setTotal(to){cancelAnimationFrame(raf);if(!shown||matchMedia('(prefers-reduced-motion:reduce)').matches){shown=to;tEl.textContent=eur(to);return}var from=shown,t0=performance.now();(function s(t){var k=Math.min(1,(t-t0)/420),e=1-Math.pow(1-k,3);shown=from+(to-from)*e;tEl.textContent=eur(shown);if(k<1)raf=requestAnimationFrame(s)})(t0)}
function calc(){var L=[['Dakkapel basis, 2 m',BASE]],tot=BASE;
G.forEach(function(g){var i=+f.querySelector('input[name="bcm-'+g.k+'"]:checked').value,o=g.o[i];if(o[2]){L.push([g.t+': '+o[0],o[2]]);tot+=o[2]}});
X.forEach(function(x){if(f.querySelector('input[name="bcm-'+x[0]+'"]').checked){L.push([x[1],x[2]]);tot+=x[2]}});
var now={};lines.innerHTML=L.map(function(l,i){now[l[0]]=1;return '<li'+(i&&!prev[l[0]]&&Object.keys(prev).length?' class="is-new"':'')+'><span>'+l[0]+'</span><b>'+(i?'+':'')+eur(l[1])+'</b></li>'}).join('');prev=now;
f.querySelectorAll('.bcm__o').forEach(function(o){o.classList.toggle('is-on',o.querySelector('input').checked)});
setTotal(tot);go.disabled=false;go.textContent='Offerte aanvragen';st.textContent=''}
f.addEventListener('change',calc);
f.addEventListener('submit',function(e){e.preventDefault();go.disabled=true;go.textContent='Versturen';setTimeout(function(){go.textContent='Aangevraagd';st.textContent='Binnen 2 werkdagen bellen we om de inmeetafspraak te plannen.'},800)});
calc();
}
init(document.querySelector('.jouw-container'));
Meer uit formulieren & invoer
Iets gezien dat je mooi vindt?
Zet het in je selectie en stuur hem op. Dan bouwen we je site eromheen, in jouw huisstijl.
Neem contact op →