Afrekenen in drie inklapbare stappen Nieuw
Compact afrekenformulier in één kolom: bezorgadres, verzendwijze en betalen als stappen die na invullen inklappen tot een samenvattingsregel met een Wijzig-knop. Postcode wordt gecontroleerd en opgemaakt, de verzendkeuze verandert het totaal dat onderaan live meeloopt, en betalen kan met iDEAL (bankkeuze) of creditcard. Volgende stappen zijn pas open als de vorige klopt. Voor webshops die afrekenen in een smalle kolom of zijpaneel willen houden.
-
Bezorgadres
-
Verzending
-
Betalen
Wandelschoenen, maat 42: € 129,95
Verzending € 4,95Totaal € 134,90
Verzending € 4,95Totaal € 134,90
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.
<!-- Afrekenen in drie inklapbare stappen · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="afs"><div class="afs__in">
<ol class="afs__steps">
<li class="afs__st is-open" data-s="adres">
<div class="afs__hd"><h4 class="afs__h" tabindex="-1">Bezorgadres</h4><p class="afs__sum"></p><button class="afs__edit" type="button" hidden>Wijzig</button></div>
<div class="afs__bd">
<div class="afs__fld"><label class="afs__l" for="afs-n">Naam</label><input class="afs__i afs__n" id="afs-n" autocomplete="name" value="Sanne de Wit"></div>
<div class="afs__two"><div class="afs__fld"><label class="afs__l" for="afs-pc">Postcode</label><input class="afs__i afs__pc" id="afs-pc" autocomplete="postal-code" placeholder="1234 AB" aria-describedby="afs-pce"></div>
<div class="afs__fld"><label class="afs__l" for="afs-hn">Huisnummer</label><input class="afs__i afs__hn" id="afs-hn" inputmode="numeric" autocomplete="address-line2" aria-describedby="afs-pce"></div></div>
<p class="afs__err" id="afs-pce"></p>
<button class="afs__next" type="button">Verder naar verzending</button>
</div></li>
<li class="afs__st" data-s="verz">
<div class="afs__hd"><h4 class="afs__h" tabindex="-1">Verzending</h4><p class="afs__sum"></p><button class="afs__edit" type="button" hidden>Wijzig</button></div>
<div class="afs__bd" hidden>
<fieldset class="afs__fs"><legend class="afs__vh">Kies een verzendwijze</legend>
<label class="afs__opt"><input type="radio" name="afs-v" value="4.95" data-t="Morgen bezorgd door PostNL" checked><span class="afs__ot">Morgen bezorgd, PostNL</span><span class="afs__op">€ 4,95</span></label>
<label class="afs__opt"><input type="radio" name="afs-v" value="6.95" data-t="Avondlevering 18:00 tot 22:00"><span class="afs__ot">Avond, 18:00 tot 22:00</span><span class="afs__op">€ 6,95</span></label>
<label class="afs__opt"><input type="radio" name="afs-v" value="0" data-t="Ophalen Oudegracht 112, Utrecht"><span class="afs__ot">Ophalen in de winkel, Utrecht</span><span class="afs__op">Gratis</span></label>
</fieldset>
<button class="afs__next" type="button">Verder naar betalen</button>
</div></li>
<li class="afs__st" data-s="bet">
<div class="afs__hd"><h4 class="afs__h" tabindex="-1">Betalen</h4><p class="afs__sum"></p></div>
<div class="afs__bd" hidden>
<fieldset class="afs__fs"><legend class="afs__vh">Kies een betaalmethode</legend>
<label class="afs__opt"><input type="radio" name="afs-b" value="ideal" checked><span class="afs__ot">iDEAL</span></label>
<div class="afs__sub afs__sub--ideal"><label class="afs__l" for="afs-bank">Je bank</label><select class="afs__i afs__bank" id="afs-bank" aria-describedby="afs-be"><option value="">Kies je bank</option><option>ABN AMRO</option><option>ASN Bank</option><option>bunq</option><option>ING</option><option>Rabobank</option><option>SNS</option><option>Triodos Bank</option></select></div>
<label class="afs__opt"><input type="radio" name="afs-b" value="kaart"><span class="afs__ot">Creditcard</span></label>
<div class="afs__sub afs__sub--kaart" hidden><label class="afs__l" for="afs-cc">Kaartnummer</label><input class="afs__i afs__cc" id="afs-cc" inputmode="numeric" autocomplete="cc-number" placeholder="1234 5678 9012 3456" aria-describedby="afs-be"></div>
</fieldset>
<p class="afs__err" id="afs-be"></p>
<button class="afs__next afs__pay" type="button">Betalen</button>
</div></li>
</ol>
<div class="afs__tot"><span>Wandelschoenen, maat 42: € 129,95<br><span class="afs__vz">Verzending € 4,95</span></span><strong class="afs__sumtot" aria-live="polite">Totaal € 134,90</strong></div>
</div></div>
</div>/* Afrekenen in drie inklapbare stappen · NedDev · eigen werk. */
.afs{position:absolute;inset:0;overflow:auto;display:flex;padding:12px;box-sizing:border-box;background:#f4f3f1;font-family:'Switzer',sans-serif;color:#0a0a0a}
.afs *,.afs *::before,.afs *::after{box-sizing:border-box}
.afs [hidden]{display:none!important}
.afs__in{margin:auto;width:100%;max-width:380px;background:#fff;border:1px solid rgba(10,10,10,.12);border-radius:8px;overflow:hidden}
.afs__steps{list-style:none;margin:0;padding:0}
.afs__st{border-bottom:1px solid rgba(10,10,10,.1);padding:10px 14px}
.afs__hd{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.afs__h{margin:0;font-size:14px;font-weight:700;outline:none;color:#6b6b6b}
.afs__st.is-open .afs__h,.afs__st.is-done .afs__h{color:#0a0a0a}
.afs__st.is-done .afs__h::before{content:'';display:inline-block;width:8px;height:8px;margin-right:7px;background:#1F7A3D;border-radius:2px;vertical-align:1px}
.afs__sum{margin:0;flex:1 1 140px;min-width:0;font-size:12.5px;color:#4a4a4a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.afs__edit{margin-left:auto;border:0;background:none;min-height:24px;padding:2px 0;font:500 12.5px 'Switzer',sans-serif;color:#0a0a0a;text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.afs__bd{padding-top:8px;animation:afs-in .22s ease}
@keyframes afs-in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
.afs__fld{margin-bottom:7px;min-width:0}
.afs__two{display:grid;grid-template-columns:1.3fr 1fr;gap:8px}
.afs__l{display:block;font-size:12.5px;font-weight:600;margin-bottom:3px}
.afs__i{display:block;width:100%;height:34px;padding:0 9px;font:400 14px 'Switzer',sans-serif;color:#0a0a0a;background:#fff;border:1px solid #8c8c8c;border-radius:4px;transition:border-color .15s,box-shadow .15s}
.afs__i:hover{border-color:#0a0a0a}
.afs__i:focus-visible{outline:none;border-color:#0a0a0a;box-shadow:0 0 0 3px rgba(245,72,15,.35)}
.afs__i[aria-invalid="true"]{border-color:#B42318}
.afs__err{margin:0 0 6px;font-size:12.5px;color:#B42318}
.afs__err:empty{display:none}
.afs__fs{border:0;margin:0 0 6px;padding:0;min-width:0;display:grid;gap:5px}
.afs__vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;padding:0}
.afs__opt{position:relative;display:flex;align-items:center;gap:9px;min-height:36px;padding:6px 10px;border:1px solid rgba(10,10,10,.2);border-radius:4px;font-size:13px;cursor:pointer;transition:border-color .15s,background-color .15s}
.afs__opt:hover{border-color:#0a0a0a}
.afs__opt:has(input:checked){border-color:#0a0a0a;box-shadow:inset 0 0 0 1px #0a0a0a;background:#faf9f7}
.afs__opt input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer}
.afs__opt::before{content:'';flex:none;width:16px;height:16px;border:1.5px solid #6b6b6b;border-radius:50%;background:#fff}
.afs__opt:has(input:checked)::before{border-color:#0a0a0a;box-shadow:inset 0 0 0 4px #fff;background:#0a0a0a}
.afs__opt:has(input:focus-visible){outline:2px solid #F5480F;outline-offset:2px}
.afs__ot{flex:1}
.afs__op{font-weight:600}
.afs__sub{padding:2px 0 4px 26px}
.afs__next{height:36px;padding:0 14px;border:0;border-radius:4px;background:#0a0a0a;color:#fff;font:600 13.5px 'Switzer',sans-serif;cursor:pointer;transition:background-color .15s}
.afs__next:hover{background:#2a2a2a}
.afs__next:active{transform:translateY(1px)}
.afs__pay{background:#F5480F;color:#0a0a0a;width:100%}
.afs__pay:hover{background:#ff6a36}
.afs__next:focus-visible,.afs__edit:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.afs__pay:focus-visible{outline-color:#0a0a0a}
.afs__tot{display:flex;justify-content:space-between;align-items:flex-end;gap:10px;padding:10px 14px;background:#f4f3f1;font-size:12.5px;color:#4a4a4a;line-height:1.4}
.afs__sumtot{font-size:14px;color:#0a0a0a;white-space:nowrap}
.afs__paid{margin:0;padding:4px 0;font-size:13px;line-height:1.4}
@media (prefers-reduced-motion:reduce){.afs *{transition:none!important;animation:none!important}}// Afrekenen in drie inklapbare stappen · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.afs');if(!w)return;
var sfx='-'+Math.random().toString(36).slice(2,7);
w.querySelectorAll('[id]').forEach(function(el){el.id=el.id+sfx;});
w.querySelectorAll('[for]').forEach(function(el){el.setAttribute('for',el.getAttribute('for')+sfx);});
w.querySelectorAll('[aria-describedby]').forEach(function(el){el.setAttribute('aria-describedby',el.getAttribute('aria-describedby')+sfx);});
w.querySelectorAll('input[type=radio]').forEach(function(r){r.name=r.name+sfx;});
var steps=[].slice.call(w.querySelectorAll('.afs__st')),SUB=129.95,ship=4.95;
var CITY={'10':'Amsterdam','25':'Den Haag','30':'Rotterdam','35':'Utrecht','56':'Eindhoven','97':'Groningen','80':'Zwolle','65':'Nijmegen'};
function eur(n){return '\u20ac\u00a0'+n.toFixed(2).replace('.',',');}
function tot(){w.querySelector('.afs__vz').textContent=ship?'Verzending '+eur(ship):'Verzending gratis';var t='Totaal '+eur(SUB+ship);w.querySelector('.afs__sumtot').textContent=t;w.querySelector('.afs__pay').textContent='Betaal '+eur(SUB+ship);}
function open(i){steps.forEach(function(s,k){var bd=s.querySelector('.afs__bd'),ed=s.querySelector('.afs__edit');bd.hidden=k!==i;s.classList.toggle('is-open',k===i);if(ed)ed.hidden=!(s.classList.contains('is-done')&&k!==i);s.querySelector('.afs__sum').hidden=k===i;});
var h=steps[i].querySelector('.afs__h');h.focus();}
function done(i,txt){var s=steps[i];s.classList.add('is-done');s.querySelector('.afs__sum').textContent=txt;}
var pc=w.querySelector('.afs__pc'),hn=w.querySelector('.afs__hn'),nm=w.querySelector('.afs__n'),pce=w.querySelector('[id^="afs-pce"]');
pc.addEventListener('blur',function(){var v=pc.value.replace(/\s/g,'').toUpperCase();if(/^[1-9]\d{3}[A-Z]{2}$/.test(v))pc.value=v.slice(0,4)+' '+v.slice(4);});
steps[0].querySelector('.afs__next').addEventListener('click',function(){var v=pc.value.replace(/\s/g,'').toUpperCase(),m='';
pc.removeAttribute('aria-invalid');hn.removeAttribute('aria-invalid');
if(!/^[1-9]\d{3}[A-Z]{2}$/.test(v)){m='Vul een postcode in zoals 3511 AB';pc.setAttribute('aria-invalid','true');}
else if(!/^\d+\s?[a-zA-Z]?$/.test(hn.value.trim())){m='Vul je huisnummer in, eventueel met toevoeging zoals 12a';hn.setAttribute('aria-invalid','true');}
pce.textContent=m;if(m){(pc.getAttribute('aria-invalid')?pc:hn).focus();return;}
pc.value=v.slice(0,4)+' '+v.slice(4);var c=CITY[v.slice(0,2)];
done(0,(nm.value.trim()||'Geen naam')+', '+pc.value+' '+hn.value.trim()+(c?', '+c:''));open(1);});
w.querySelectorAll('input[name^="afs-v"]').forEach(function(r){r.addEventListener('change',function(){ship=parseFloat(r.value);tot();});});
steps[1].querySelector('.afs__next').addEventListener('click',function(){var r=w.querySelector('input[name^="afs-v"]:checked');done(1,r.getAttribute('data-t')+(ship?', '+eur(ship):''));open(2);});
var subI=w.querySelector('.afs__sub--ideal'),subK=w.querySelector('.afs__sub--kaart'),bank=w.querySelector('.afs__bank'),cc=w.querySelector('.afs__cc'),be=w.querySelector('[id^="afs-be"]');
w.querySelectorAll('input[name^="afs-b"]').forEach(function(r){r.addEventListener('change',function(){subI.hidden=r.value!=='ideal';subK.hidden=r.value!=='kaart';be.textContent='';});});
cc.addEventListener('input',function(){var d=cc.value.replace(/\D/g,'').slice(0,19);cc.value=d.replace(/(\d{4})(?=\d)/g,'$1 ');});
steps.forEach(function(s,i){var ed=s.querySelector('.afs__edit');if(ed)ed.addEventListener('click',function(){open(i);});});
w.querySelector('.afs__pay').addEventListener('click',function(){var m=w.querySelector('input[name^="afs-b"]:checked').value,err='';
bank.removeAttribute('aria-invalid');cc.removeAttribute('aria-invalid');
if(m==='ideal'&&!bank.value){err='Kies je bank om met iDEAL te betalen';bank.setAttribute('aria-invalid','true');}
if(m==='kaart'&&cc.value.replace(/\D/g,'').length<15){err='Vul het volledige kaartnummer in';cc.setAttribute('aria-invalid','true');}
be.textContent=err;if(err){(m==='ideal'?bank:cc).focus();return;}
var b=w.querySelector('.afs__pay');b.textContent=m==='ideal'?'Je gaat naar '+bank.value:'Bezig met betalen';b.disabled=true;
setTimeout(function(){var bd=steps[2].querySelector('.afs__bd');done(2,m==='ideal'?'iDEAL, '+bank.value:'Creditcard, eindigend op '+cc.value.replace(/\D/g,'').slice(-4));
bd.innerHTML='<p class="afs__paid" role="status">Betaald. Bestelnummer 40712, de bevestiging staat in je mail.</p>';steps.forEach(function(s){var e=s.querySelector('.afs__edit');if(e)e.hidden=true;s.querySelector('.afs__sum').hidden=false;});},900);});
tot();open(0);w.querySelector('.afs__h').blur();
}
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 →