Registreren met wachtwoordeisen die afvinken Nieuw
Registratieformulier waarin de wachtwoordeisen als lijst onder het veld staan en één voor één worden afgevinkt terwijl je typt: lengte, hoofd- en kleine letter, cijfer en niet je eigen e-mailadres. De voortgang wordt rustig voorgelezen (aria-live, met vertraging), de knop blijft bruikbaar en noemt bij versturen precies welke eis nog ontbreekt. Voor webshops, portalen en SaaS-aanmeldingen.
Bijna klaar
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.
<!-- Registreren met wachtwoordeisen die afvinken · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="rgl"><div class="rgl__in">
<form class="rgl__form" novalidate>
<h3 class="rgl__h" tabindex="-1">Account aanmaken</h3>
<p class="rgl__sub">Tuincentrum De Linde, Bunnik. Bestel online en haal op in de winkel.</p>
<div class="rgl__fld"><label class="rgl__l" for="rgl-e">E-mailadres</label><input class="rgl__i rgl__e" id="rgl-e" type="email" autocomplete="email" aria-describedby="rgl-ee"><p class="rgl__err" id="rgl-ee"></p></div>
<div class="rgl__fld"><label class="rgl__l" for="rgl-p">Kies een wachtwoord</label>
<div class="rgl__pw"><input class="rgl__i rgl__p" id="rgl-p" type="password" autocomplete="new-password" aria-describedby="rgl-rules rgl-pe"><button class="rgl__show" type="button" aria-pressed="false" aria-label="Wachtwoord tonen">Toon</button></div>
<ul class="rgl__rules" id="rgl-rules" aria-label="Eisen voor je wachtwoord">
<li data-r="len"><svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="6.5"/><path d="M4.8 8.3l2.2 2.2 4.3-4.6"/></svg><span>Minstens 10 tekens</span><span class="rgl__st"> (nog niet)</span></li>
<li data-r="case"><svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="6.5"/><path d="M4.8 8.3l2.2 2.2 4.3-4.6"/></svg><span>Een hoofdletter en een kleine letter</span><span class="rgl__st"> (nog niet)</span></li>
<li data-r="dig"><svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="6.5"/><path d="M4.8 8.3l2.2 2.2 4.3-4.6"/></svg><span>Minstens één cijfer</span><span class="rgl__st"> (nog niet)</span></li>
<li data-r="mail"><svg viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="6.5"/><path d="M4.8 8.3l2.2 2.2 4.3-4.6"/></svg><span>Bevat niet je e-mailadres</span><span class="rgl__st"> (nog niet)</span></li>
</ul>
<p class="rgl__err" id="rgl-pe"></p></div>
<button class="rgl__btn" type="submit">Account aanmaken</button>
<p class="rgl__sr" aria-live="polite"></p>
</form>
<div class="rgl__done" hidden><h3 class="rgl__h" tabindex="-1">Bijna klaar</h3><p class="rgl__sub rgl__donemsg"></p><button class="rgl__link" type="button">Opnieuw proberen</button></div>
</div></div>
</div>/* Registreren met wachtwoordeisen die afvinken · NedDev · eigen werk. */
.rgl{position:absolute;inset:0;overflow:auto;display:flex;padding:14px;box-sizing:border-box;background:#f4f3f1;font-family:'Switzer',sans-serif;color:#0a0a0a}
.rgl *,.rgl *::before,.rgl *::after{box-sizing:border-box}
.rgl [hidden]{display:none!important}
.rgl__in{margin:auto;width:100%;max-width:360px;background:#fff;border:1px solid rgba(10,10,10,.12);border-radius:8px;padding:16px}
.rgl__h{margin:0;font-size:17px;font-weight:700;letter-spacing:-.01em;outline:none}
.rgl__sub{margin:3px 0 10px;font-size:13px;line-height:1.4;color:#4a4a4a}
.rgl__fld{margin-bottom:9px}
.rgl__l{display:block;font-size:13px;font-weight:600;margin-bottom:4px}
.rgl__i{display:block;width:100%;height:36px;padding:0 10px;font:400 14px 'Switzer',sans-serif;color:#0a0a0a;background:#fff;border:1px solid #8c8c8c;border-radius:4px;transition:border-color .15s,box-shadow .15s}
.rgl__i:hover{border-color:#0a0a0a}
.rgl__i:focus-visible{outline:none;border-color:#0a0a0a;box-shadow:0 0 0 3px rgba(245,72,15,.35)}
.rgl__i[aria-invalid="true"]{border-color:#B42318}
.rgl__pw{position:relative}
.rgl__pw .rgl__i{padding-right:72px}
.rgl__show{position:absolute;right:4px;top:4px;height:28px;padding:0 9px;border:0;border-radius:4px;background:#f4f3f1;font:600 12.5px 'Switzer',sans-serif;color:#0a0a0a;cursor:pointer}
.rgl__show:hover{background:#e7e4df}
.rgl__rules{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:4px}
.rgl__rules li{display:flex;align-items:center;gap:7px;font-size:12.5px;color:#4a4a4a;transition:color .2s}
.rgl__rules svg{flex:none;width:16px;height:16px;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.rgl__rules circle{stroke:#a3a09a;transition:stroke .2s,fill .2s}
.rgl__rules path{stroke:#fff;stroke-dasharray:12;stroke-dashoffset:12;transition:stroke-dashoffset .3s ease .05s}
.rgl__rules li.is-ok{color:#0a0a0a}
.rgl__rules li.is-ok circle{stroke:#1F7A3D;fill:#1F7A3D}
.rgl__rules li.is-ok path{stroke-dashoffset:0}
.rgl__rules li.is-miss{color:#B42318}
.rgl__rules li.is-miss circle{stroke:#B42318}
.rgl__st{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.rgl__err{margin:4px 0 0;font-size:12.5px;color:#B42318;line-height:1.35}
.rgl__err:empty{display:none}
.rgl__btn{width:100%;height:40px;margin-top:4px;border:0;border-radius:4px;background:#0a0a0a;color:#fff;font:600 14px 'Switzer',sans-serif;cursor:pointer;transition:background-color .15s}
.rgl__btn:hover{background:#2a2a2a}
.rgl__btn:active{transform:translateY(1px)}
.rgl__link{border:0;background:none;padding:4px 0;min-height:24px;font:500 13px 'Switzer',sans-serif;color:#0a0a0a;text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.rgl__show:focus-visible,.rgl__btn:focus-visible,.rgl__link:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.rgl__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;margin:0}
@media (prefers-reduced-motion:reduce){.rgl *{transition:none!important}}// Registreren met wachtwoordeisen die afvinken · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.rgl');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').split(' ').map(function(x){return x+sfx;}).join(' '));});
var f=w.querySelector('.rgl__form'),e=w.querySelector('.rgl__e'),p=w.querySelector('.rgl__p'),ee=w.querySelector('[id^="rgl-ee"]'),pe=w.querySelector('[id^="rgl-pe"]'),sr=w.querySelector('.rgl__sr'),done=w.querySelector('.rgl__done'),tm,lastN=-1;
var items=[].slice.call(w.querySelectorAll('.rgl__rules li'));
var RE=/^[^\s@]+@[^\s@]+\.[a-z]{2,}$/i;
var TXT={len:'minstens 10 tekens',case:'een hoofdletter en een kleine letter',dig:'een cijfer',mail:'geen e-mailadres in je wachtwoord'};
function test(){var v=p.value,m=e.value.trim().toLowerCase(),loc=m.split('@')[0];
return {len:v.length>=10,case:/[a-z]/.test(v)&&/[A-Z]/.test(v),dig:/\d/.test(v),mail:v.length>0&&!(m&&v.toLowerCase().indexOf(m)>-1)&&!(loc.length>3&&v.toLowerCase().indexOf(loc)>-1)};}
function paint(strict){var t=test(),n=0;items.forEach(function(li){var k=li.getAttribute('data-r'),ok=t[k];if(ok)n++;li.classList.toggle('is-ok',ok);li.classList.toggle('is-miss',!ok&&strict);li.querySelector('.rgl__st').textContent=ok?' (gehaald)':' (nog niet)';});
if(n===items.length){pe.textContent='';p.removeAttribute('aria-invalid');}
return {t:t,n:n};}
p.addEventListener('input',function(){var r=paint(p.getAttribute('aria-invalid')==='true');clearTimeout(tm);
tm=setTimeout(function(){if(r.n!==lastN&&p.value){sr.textContent=r.n===items.length?'Je wachtwoord voldoet aan alle eisen':r.n+' van '+items.length+' eisen gehaald';lastN=r.n;}},700);});
e.addEventListener('input',function(){paint(false);if(e.getAttribute('aria-invalid'))chkE();});
function chkE(){var v=e.value.trim(),m=!v?'Vul je e-mailadres in':!RE.test(v)?'Dit lijkt geen e-mailadres, bijvoorbeeld naam@voorbeeld.nl':'';ee.textContent=m;if(m)e.setAttribute('aria-invalid','true');else e.removeAttribute('aria-invalid');return !m;}
e.addEventListener('blur',function(){if(e.value)chkE();});
var sb=w.querySelector('.rgl__show');sb.addEventListener('click',function(){var on=p.type==='password';p.type=on?'text':'password';sb.textContent=on?'Verberg':'Toon';sb.setAttribute('aria-pressed',on);sb.setAttribute('aria-label',on?'Wachtwoord verbergen':'Wachtwoord tonen');});
f.addEventListener('submit',function(ev){ev.preventDefault();var okE=chkE(),r=paint(true);
var miss=items.filter(function(li){return !r.t[li.getAttribute('data-r')];}).map(function(li){return TXT[li.getAttribute('data-r')];});
if(miss.length){pe.textContent='Je wachtwoord mist nog: '+miss.join(', ')+'.';p.setAttribute('aria-invalid','true');}
if(!okE){e.focus();return;}if(miss.length){p.focus();return;}
f.hidden=true;done.hidden=false;w.querySelector('.rgl__donemsg').textContent='We stuurden een bevestigingslink naar '+e.value.trim()+'. Klik daarop om je account te activeren.';done.querySelector('.rgl__h').focus();});
done.querySelector('.rgl__link').addEventListener('click',function(){f.reset();p.type='password';sb.textContent='Toon';sb.setAttribute('aria-pressed','false');lastN=-1;paint(false);done.hidden=true;f.hidden=false;f.querySelector('.rgl__h').focus();});
paint(false);
}
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 →