Getrapt contactformulier New
Three-step form: first the type of request (quote, breakdown, question), then the matching fields, then contact details. With progress, client-side validation and a confirmation.
Warmte Nu Installatietechniek · Apeldoorn
Waar kunnen we mee helpen?
Bij een storing bellen we binnen twee uur terug, ook in het weekend. Een offerte heeft u binnen drie werkdagen.
Liever bellen? 055 123 4567
How to use it
- Paste the HTML where the page sections should appear.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- Getrapt contactformulier · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="cgt">
<div class="cgt__in">
<div class="cgt__intro">
<span class="cgt__eye">Warmte Nu Installatietechniek · Apeldoorn</span>
<h2 class="cgt__h">Waar kunnen we mee helpen?</h2>
<p class="cgt__lead">Bij een storing bellen we binnen twee uur terug, ook in het weekend. Een offerte heeft u binnen drie werkdagen.</p>
<p class="cgt__lead cgt__lead--sm">Liever bellen? <a href="tel:+31551234567">055 123 4567</a></p>
</div>
<form class="cgt__form" novalidate>
<div class="cgt__prog" aria-hidden="true"><span class="cgt__dot is-on">1 Soort</span><span class="cgt__dot">2 Details</span><span class="cgt__dot">3 Gegevens</span><i class="cgt__fill"></i></div>
<fieldset class="cgt__step is-on" data-s="1">
<legend class="cgt__lg">Stap 1 van 3 · Wat voor vraag heeft u?</legend>
<div class="cgt__opts">
<label class="cgt__opt"><input type="radio" name="soort" value="offerte"><span><b>Offerte</b>Warmtepomp, cv-ketel of airco laten plaatsen</span></label>
<label class="cgt__opt"><input type="radio" name="soort" value="storing"><span><b>Storing</b>Geen warmte of warm water, foutcode op het display</span></label>
<label class="cgt__opt"><input type="radio" name="soort" value="vraag"><span><b>Vraag</b>Over onderhoud, subsidie of een bestaande factuur</span></label>
</div>
<p class="cgt__err" data-for="soort"></p>
</fieldset>
<fieldset class="cgt__step" data-s="2">
<legend class="cgt__lg">Stap 2 van 3 · <span class="cgt__lg2"></span></legend>
<div class="cgt__grp" data-g="offerte">
<label class="cgt__f"><span>Wat wilt u laten plaatsen?</span><select name="product" data-req><option value="">Kies een optie</option><option>Hybride warmtepomp</option><option>Volledig elektrische warmtepomp</option><option>Nieuwe cv-ketel</option><option>Airco</option></select></label>
<div class="cgt__two"><label class="cgt__f"><span>Bouwjaar woning</span><input name="bouwjaar" inputmode="numeric" placeholder="bv. 1978" data-req data-pat="^(1[89]|20)\d{2}$" data-msg="Vul een bouwjaar in, bv. 1978"></label><label class="cgt__f"><span>Postcode</span><input name="pc1" placeholder="7311 AB" data-req data-pat="^[1-9][0-9]{3} ?[A-Za-z]{2}$" data-msg="Postcode als 7311 AB"></label></div>
</div>
<div class="cgt__grp" data-g="storing">
<label class="cgt__f"><span>Merk toestel</span><select name="merk" data-req><option value="">Kies een merk</option><option>Remeha</option><option>Intergas</option><option>Nefit</option><option>Vaillant</option><option>Daikin</option><option>Weet ik niet</option></select></label>
<div class="cgt__two"><label class="cgt__f"><span>Foutcode (indien zichtbaar)</span><input name="code" placeholder="bv. E04 of H.02"></label><label class="cgt__f"><span>Postcode</span><input name="pc2" placeholder="7311 AB" data-req data-pat="^[1-9][0-9]{3} ?[A-Za-z]{2}$" data-msg="Postcode als 7311 AB"></label></div>
<label class="cgt__chk"><input type="checkbox" name="water"> Er lekt water uit het toestel</label>
</div>
<div class="cgt__grp" data-g="vraag">
<label class="cgt__f"><span>Onderwerp</span><select name="onderwerp" data-req><option value="">Kies een onderwerp</option><option>Onderhoudscontract</option><option>Subsidie (ISDE)</option><option>Factuur</option><option>Iets anders</option></select></label>
<label class="cgt__f"><span>Uw vraag</span><textarea name="tekst" rows="3" data-req data-min="10" data-msg="Schrijf minimaal 10 tekens"></textarea></label>
</div>
</fieldset>
<fieldset class="cgt__step" data-s="3">
<legend class="cgt__lg">Stap 3 van 3 · Hoe bereiken we u?</legend>
<label class="cgt__f"><span>Naam</span><input name="naam" autocomplete="name" data-req data-min="2" data-msg="Vul uw naam in"></label>
<div class="cgt__two"><label class="cgt__f"><span>Telefoon</span><input name="tel" type="tel" autocomplete="tel" data-req data-pat="^(\+31|0)[1-9][0-9 -]{8,11}$" data-msg="Bv. 06 1234 5678"></label><label class="cgt__f"><span>E-mail</span><input name="mail" type="email" autocomplete="email" data-req data-pat="^[^@\s]+@[^@\s]+\.[a-z]{2,}$" data-msg="Bv. naam@voorbeeld.nl"></label></div>
</fieldset>
<div class="cgt__done" role="status" tabindex="-1"><svg viewBox="0 0 48 48" aria-hidden="true"><circle cx="24" cy="24" r="22" fill="#0b4f6c"/><path d="M14 24l7 7 13-14" stroke="#fff" stroke-width="4" fill="none"/></svg><b></b><p></p><button type="button" class="cgt__btn cgt__btn--ghost cgt__again">Nieuwe aanvraag</button></div>
<div class="cgt__nav"><button type="button" class="cgt__btn cgt__btn--ghost cgt__back">Terug</button><button type="submit" class="cgt__btn cgt__next">Volgende</button></div>
</form>
</div>
</div>
</div>/* Getrapt contactformulier · NedDev · eigen werk. */
.cgt{background:#e9f1f4;color:#0e2a36;font-family:'Switzer',sans-serif;box-sizing:border-box}
.cgt *{box-sizing:border-box}
.cgt__in{max-width:1180px;margin:0 auto;padding:40px 32px;display:grid;grid-template-columns:.85fr 1.15fr;gap:40px;align-items:start}
.cgt__eye{font:500 11px 'JetBrains Mono',monospace;letter-spacing:.14em;text-transform:uppercase;color:#0b4f6c}
.cgt__h{font-size:clamp(26px,3.2vw,40px);font-weight:800;letter-spacing:-.025em;line-height:1.05;margin:10px 0 14px}
.cgt__lead{font-size:15px;line-height:1.55;color:#3d5560;margin:0 0 12px;max-width:38ch}
.cgt__lead--sm{font-size:14px}.cgt__lead a{color:#0b4f6c;font-weight:700}
.cgt__form{background:#fff;border-radius:6px;padding:22px 24px;box-shadow:0 1px 0 #cfdde3;position:relative}
.cgt__prog{display:flex;justify-content:space-between;position:relative;margin-bottom:20px;padding-bottom:12px;font:500 11px 'JetBrains Mono',monospace;color:#8aa0aa;letter-spacing:.06em}
.cgt__prog::before,.cgt__fill{content:'';position:absolute;left:0;bottom:0;height:3px;border-radius:2px;background:#dbe6ea;width:100%}
.cgt__fill{background:#f2a541;width:33.33%;transition:width .4s cubic-bezier(.2,.8,.2,1)}
.cgt__dot.is-on{color:#0b4f6c;font-weight:700}
.cgt__step{border:0;margin:0;padding:0;display:none;min-width:0}
.cgt__step.is-on{display:block;animation:cgt-in .35s ease}
.cgt__lg{font-weight:700;font-size:16px;padding:0;margin-bottom:14px}
.cgt__opts{display:grid;gap:10px}
.cgt__opt{display:flex;gap:12px;align-items:flex-start;border:1px solid #cfdde3;border-radius:4px;padding:12px 14px;cursor:pointer;transition:border-color .2s,background .2s}
.cgt__opt input{accent-color:#0b4f6c;margin-top:3px}
.cgt__opt span{display:flex;flex-direction:column;font-size:13.5px;color:#4d6570}
.cgt__opt b{font-size:15px;color:#0e2a36}
.cgt__opt:hover{border-color:#0b4f6c}
.cgt__opt:has(input:checked){border-color:#0b4f6c;background:#eef5f8;box-shadow:inset 3px 0 0 #f2a541}
.cgt__grp{display:none}.cgt__grp.is-on{display:block}
.cgt__two{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.cgt__f{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}
.cgt__f>span{font-size:12.5px;font-weight:600;color:#3d5560}
.cgt__f input,.cgt__f select,.cgt__f textarea{font:400 15px 'Switzer',sans-serif;color:#0e2a36;border:1px solid #b9cbd2;border-radius:3px;padding:10px 12px;background:#fff;width:100%;resize:vertical}
.cgt__f input:focus,.cgt__f select:focus,.cgt__f textarea:focus{outline:2px solid #0b4f6c;outline-offset:-1px}
.cgt__f .is-bad{border-color:#c0392b;background:#fff6f4}
.cgt__f small,.cgt__err{color:#c0392b;font-size:12.5px;margin:0;min-height:0}
.cgt__err:empty{display:none}.cgt__err{margin-top:8px}
.cgt__chk{display:flex;gap:8px;align-items:center;font-size:14px;color:#3d5560}
.cgt__chk input{accent-color:#0b4f6c}
.cgt__nav{display:flex;justify-content:space-between;gap:10px;margin-top:16px}
.cgt__btn{font:700 15px 'Switzer',sans-serif;border-radius:3px;padding:12px 22px;cursor:pointer;border:1px solid #0b4f6c;background:#0b4f6c;color:#fff;transition:background .2s,color .2s}
.cgt__btn:hover{background:#0e2a36;border-color:#0e2a36}
.cgt__btn--ghost{background:transparent;color:#0b4f6c}
.cgt__btn--ghost:hover{background:#eef5f8;color:#0e2a36}
.cgt__btn:focus-visible{outline:2px solid #f2a541;outline-offset:2px}
.cgt__back[hidden]{display:inline-block;visibility:hidden}
.cgt__done{display:none;text-align:center;padding:20px 10px 8px;outline:none}
.cgt__done.is-on{display:block;animation:cgt-in .4s ease}
.cgt__done svg{width:52px;height:52px}
.cgt__done b{display:block;font-size:20px;margin:12px 0 6px}
.cgt__done p{margin:0 auto 18px;max-width:40ch;color:#3d5560;font-size:14.5px;line-height:1.5}
@keyframes cgt-in{from{opacity:0;transform:translateX(12px)}to{opacity:1;transform:none}}
@media(max-width:820px){.cgt__in{grid-template-columns:1fr;gap:18px;padding:28px 16px}.cgt__form{padding:18px 16px}.cgt__lead--sm{display:none}}
@media(max-width:420px){.cgt__two{grid-template-columns:1fr;gap:0}.cgt__prog{font-size:10px}}
@media(prefers-reduced-motion:reduce){.cgt__step.is-on,.cgt__done.is-on{animation:none}.cgt__fill{transition:none}}// Getrapt contactformulier · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.cgt');if(!w)return;
var f=w.querySelector('.cgt__form'),steps=w.querySelectorAll('.cgt__step'),dots=w.querySelectorAll('.cgt__dot'),fill=w.querySelector('.cgt__fill');
var back=w.querySelector('.cgt__back'),next=w.querySelector('.cgt__next'),nav=w.querySelector('.cgt__nav'),done=w.querySelector('.cgt__done');
var cur=1,soort='';var T={offerte:'Over de installatie',storing:'Over de storing',vraag:'Over uw vraag'};
function go(n){cur=n;steps.forEach(function(s){s.classList.toggle('is-on',+s.getAttribute('data-s')===n);});
dots.forEach(function(d,i){d.classList.toggle('is-on',i<n);});fill.style.width=(n/3*100)+'%';back.hidden=n===1;next.textContent=n===3?'Verstuur':'Volgende';
if(n===2){w.querySelector('.cgt__lg2').textContent=T[soort];w.querySelectorAll('.cgt__grp').forEach(function(g){g.classList.toggle('is-on',g.getAttribute('data-g')===soort);});}}
function msg(el,t){var lab=el.closest('.cgt__f');var s=lab.querySelector('small');if(!s){s=document.createElement('small');lab.appendChild(s);}s.textContent=t||'';el.classList.toggle('is-bad',!!t);if(t)el.setAttribute('aria-invalid','true');else el.removeAttribute('aria-invalid');}
function check(scope){var first=null;scope.querySelectorAll('[data-req]').forEach(function(el){if(el.offsetParent===null)return;var v=el.value.trim();var bad='';
if(!v)bad=el.tagName==='SELECT'?'Maak een keuze':'Dit veld is verplicht';
else if(el.getAttribute('data-pat')&&!new RegExp(el.getAttribute('data-pat'),'i').test(v))bad=el.getAttribute('data-msg');
else if(el.getAttribute('data-min')&&v.length<+el.getAttribute('data-min'))bad=el.getAttribute('data-msg');
msg(el,bad);if(bad&&!first)first=el;});if(first)first.focus();return !first;}
f.addEventListener('input',function(e){if(e.target.classList.contains('is-bad'))msg(e.target,'');});
f.addEventListener('change',function(e){if(e.target.name==='soort'){w.querySelector('.cgt__err').textContent='';}});
f.addEventListener('submit',function(e){e.preventDefault();
if(cur===1){var c=f.querySelector('input[name=soort]:checked');if(!c){w.querySelector('.cgt__err').textContent='Kies eerst wat voor vraag u heeft.';f.querySelector('input[name=soort]').focus();return;}soort=c.value;go(2);return;}
if(!check(steps[cur-1]))return;
if(cur===2){go(3);return;}
steps.forEach(function(s){s.classList.remove('is-on');});nav.style.display='none';fill.style.width='100%';
var naam=f.elements.naam.value.trim().split(' ')[0];
done.querySelector('b').textContent='Bedankt, '+naam+'.';
done.querySelector('p').textContent=soort==='storing'?'Een monteur belt u binnen twee uur terug op '+f.elements.tel.value.trim().replace(/ /g,String.fromCharCode(160))+'.':soort==='offerte'?'U ontvangt de offerte binnen drie werkdagen op '+f.elements.mail.value.trim()+'.':'We beantwoorden uw vraag binnen één werkdag per mail.';
done.classList.add('is-on');done.focus();});
back.addEventListener('click',function(){if(cur>1)go(cur-1);});
w.querySelector('.cgt__again').addEventListener('click',function(){f.reset();f.querySelectorAll('.is-bad').forEach(function(el){msg(el,'');});done.classList.remove('is-on');nav.style.display='';soort='';go(1);});
go(1);
}
init(document.querySelector('.jouw-container'));
More page sections
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →