Kenteken in NL-geel Nieuw
Kentekeninvoer in de vorm van een gele Nederlandse kentekenplaat met blauwe NL-band: hoofdletters en streepjes volgens de RDW-sidecodes (GH-482-T, KZN-12-P), validatie met een concrete foutmelding, een laadstaat en een voorbeeldresultaat met merk, model en APK-datum. Demo-data in de JS; in productie koppel je RDW Open Data (opendata.rdw.nl, gratis).
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.
<!-- Kenteken in NL-geel · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="knl"><div class="knl__in">
<form class="knl__form" novalidate>
<label class="knl__l" for="knl-k">Kenteken van je auto</label>
<div class="knl__row">
<div class="knl__plate"><span class="knl__eu" aria-hidden="true"><svg viewBox="0 0 20 20"><g fill="#F7C600"><circle cx="10" cy="3" r="1"/><circle cx="13.5" cy="3.9" r="1"/><circle cx="16.1" cy="6.5" r="1"/><circle cx="17" cy="10" r="1"/><circle cx="16.1" cy="13.5" r="1"/><circle cx="13.5" cy="16.1" r="1"/><circle cx="10" cy="17" r="1"/><circle cx="6.5" cy="16.1" r="1"/><circle cx="3.9" cy="13.5" r="1"/><circle cx="3" cy="10" r="1"/><circle cx="3.9" cy="6.5" r="1"/><circle cx="6.5" cy="3.9" r="1"/></g></svg><b>NL</b></span><input class="knl__i" id="knl-k" name="kenteken" autocomplete="off" autocapitalize="characters" spellcheck="false" maxlength="8" placeholder="GH-482-T" aria-describedby="knl-e knl-h"></div>
<button class="knl__btn" type="submit">Check</button>
</div>
<p class="knl__e" id="knl-e"></p>
<p class="knl__h" id="knl-h">Probeer <button type="button" data-k="GH482T">GH-482-T</button> <button type="button" data-k="KZN12P">KZN-12-P</button> <button type="button" data-k="S517FL">S-517-FL</button> <button type="button" data-k="BB001B">BB-001-B</button></p>
</form>
<div class="knl__res" aria-live="polite"></div>
</div></div>
</div>/* Kenteken in NL-geel · NedDev · eigen werk. */
.knl [hidden]{display:none!important}
.knl{position:absolute;inset:0;overflow:auto;display:flex;padding:14px;box-sizing:border-box;background:#f4f3f1;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;scrollbar-width:thin}
.knl *,.knl *::before,.knl *::after{box-sizing:border-box}
.knl__in{margin:auto;width:100%;max-width:400px}
.knl__l{display:block;font-size:13px;font-weight:600;margin-bottom:6px}
.knl__row{display:flex;gap:8px;align-items:stretch}
.knl__plate{flex:1;min-width:0;display:flex;background:#F7C600;border:2px solid #0a0a0a;border-radius:6px;overflow:hidden;box-shadow:inset 0 0 0 2px #F7C600,inset 0 0 0 3px rgba(10,10,10,.5);transition:box-shadow .15s}
.knl__plate:focus-within{outline:3px solid #F5480F;outline-offset:2px}
.knl[data-s="err"] .knl__plate{border-color:#B42318;outline-color:#B42318}
.knl__eu{flex:none;width:34px;background:#0039A6;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;padding:4px 0}
.knl__eu svg{width:18px;height:18px}
.knl__eu b{color:#fff;font:700 11px 'Switzer',system-ui,sans-serif;letter-spacing:.04em}
.knl__i{flex:1;min-width:0;width:100%;border:0;background:transparent;font:700 26px/1 'JetBrains Mono',monospace;letter-spacing:.06em;text-transform:uppercase;text-align:center;color:#0a0a0a;padding:10px 8px;outline:none}
.knl__i::placeholder{color:rgba(10,10,10,.28)}
.knl__btn{flex:none;font:700 14px 'Switzer',system-ui,sans-serif;padding:0 18px;border-radius:6px;border:1px solid #0a0a0a;background:#0a0a0a;color:#fff;cursor:pointer;transition:background .15s,color .15s,border-color .15s}
.knl__btn:hover{background:#F5480F;border-color:#F5480F;color:#0a0a0a}
.knl__btn:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.knl__btn[aria-busy="true"]{cursor:progress;background:#3a3a3a;border-color:#3a3a3a;color:#fff}
.knl__e{margin:6px 0 0;font-size:12.5px;color:#B42318;line-height:1.35}
.knl__e:empty{display:none}
.knl__h{margin:8px 0 0;font-size:11.5px;color:#5a5a5a;display:flex;flex-wrap:wrap;gap:4px;align-items:center}
.knl__h button{font:600 11px 'JetBrains Mono',monospace;background:#fff;border:1px solid rgba(10,10,10,.22);border-radius:3px;padding:3px 6px;color:#0a0a0a;cursor:pointer;transition:border-color .15s}
.knl__h button:hover{border-color:#0a0a0a}
.knl__h button:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.knl__res{margin-top:10px}
.knl__res:empty{display:none}
.knl__card{background:#fff;border:1px solid rgba(10,10,10,.12);border-radius:6px;padding:12px 14px;animation:knl-in .25s ease-out}
@keyframes knl-in{from{opacity:0;transform:translateY(4px)}}
.knl__car{display:flex;justify-content:space-between;gap:8px;align-items:baseline;flex-wrap:wrap;margin-bottom:6px}
.knl__car b{font-size:15.5px}
.knl__car span{font-size:12px;color:#5a5a5a}
.knl__dl{margin:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.knl__dl dt{font:500 9.5px 'JetBrains Mono',monospace;letter-spacing:.08em;text-transform:uppercase;color:#5a5a5a}
.knl__dl dd{margin:2px 0 0;font-size:13px;font-weight:600}
.knl__pill{display:inline-block;margin-top:3px;font:600 10px 'Switzer',system-ui,sans-serif;padding:2px 7px;border-radius:100px}
.knl__pill.is-ok{background:#e3f1e8;color:#0f5535}.knl__pill.is-warn{background:#fdf0dc;color:#7a4300}.knl__pill.is-bad{background:#fbe6e4;color:#9b1c13}
.knl__src{margin:8px 0 0;font-size:11px;color:#6b6b6b}
.knl__sk{display:grid;gap:7px;background:#fff;border:1px solid rgba(10,10,10,.12);border-radius:6px;padding:14px}
.knl__sk i{display:block;height:11px;border-radius:3px;background:linear-gradient(90deg,#eeece8 25%,#f7f6f3 50%,#eeece8 75%);background-size:200% 100%;animation:knl-sh 1s linear infinite}
.knl__sk i:nth-child(1){width:55%;height:14px}.knl__sk i:nth-child(2){width:80%}.knl__sk i:nth-child(3){width:65%}
@keyframes knl-sh{to{background-position:-200% 0}}
.knl__nf{background:#fff;border:1px solid rgba(10,10,10,.12);border-radius:6px;padding:12px 14px;font-size:13px;line-height:1.45}
.knl__nf button{margin-top:8px;font:600 12.5px 'Switzer',system-ui,sans-serif;background:#fff;border:1px solid #0a0a0a;border-radius:4px;padding:6px 12px;cursor:pointer;color:#0a0a0a}
.knl__nf button:hover{background:#0a0a0a;color:#fff}
.knl__nf button:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
@media (prefers-reduced-motion:reduce){.knl *{transition:none!important;animation:none!important}}// Kenteken in NL-geel · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
root=root.querySelector('.knl')||root;
var sfx='-'+Math.random().toString(36).slice(2,7);['knl-k','knl-e','knl-h'].forEach(function(o){var el=root.querySelector('#'+o);if(el)el.id=o+sfx;});
var form=root.querySelector('.knl__form'),inp=root.querySelector('.knl__i'),btn=root.querySelector('.knl__btn'),e=root.querySelector('.knl__e'),h=root.querySelector('.knl__h'),res=root.querySelector('.knl__res');
root.querySelector('.knl__l').setAttribute('for',inp.id);inp.setAttribute('aria-describedby',e.id+' '+h.id);
var SC=[/^([A-Z]{2})(\d{2})(\d{2})$/,/^(\d{2})(\d{2})([A-Z]{2})$/,/^(\d{2})([A-Z]{2})(\d{2})$/,/^([A-Z]{2})(\d{2})([A-Z]{2})$/,/^([A-Z]{2})([A-Z]{2})(\d{2})$/,/^(\d{2})([A-Z]{2})([A-Z]{2})$/,/^(\d{2})([A-Z]{3})(\d)$/,/^(\d)([A-Z]{3})(\d{2})$/,/^([A-Z]{2})(\d{3})([A-Z])$/,/^([A-Z])(\d{3})([A-Z]{2})$/,/^([A-Z]{3})(\d{2})([A-Z])$/,/^([A-Z])(\d{2})([A-Z]{3})$/,/^(\d)([A-Z]{2})(\d{3})$/,/^(\d{3})([A-Z]{2})(\d)$/];
var DAG=['zo','ma','di','wo','do','vr','za'],MND=['jan','feb','mrt','apr','mei','jun','jul','aug','sep','okt','nov','dec'];
var CARS=[['Volkswagen Golf','1.5 eTSI','Benzine'],['Toyota Yaris','1.5 Hybrid','Hybride'],['Kia Niro','EV 64 kWh','Elektrisch'],['Peugeot 208','1.2 PureTech','Benzine'],['Skoda Octavia Combi','2.0 TDI','Diesel'],['Tesla Model Y','Long Range','Elektrisch'],['Renault Clio','TCe 90','Benzine'],['Volvo XC40','Recharge','Elektrisch'],['Opel Corsa','1.2','Benzine'],['Ford Transit Custom','2.0 EcoBlue','Diesel']];
var KLEUR=['Grijs','Zwart','Wit','Blauw','Rood','Zilver','Groen'];
var FIX={GH482T:[0,'Grijs',2019,150],KZN12P:[1,'Wit',2017,34],S517FL:[8,'Blauw',2011,-21]},NOTFOUND={BB001B:1};
function clean(v){return v.toUpperCase().replace(/[^A-Z0-9]/g,'');}
function fmt(c){if(c.length===6){for(var i=0;i<SC.length;i++){var m=c.match(SC[i]);if(m)return m.slice(1).join('-');}}
var o='';for(var j=0;j<c.length;j++){if(j&&(/\d/.test(c[j])!==/\d/.test(c[j-1])))o+='-';o+=c[j];}return o;}
function valid(c){return c.length===6&&SC.some(function(r){return r.test(c);});}
function apply(){var v=inp.value,p=inp.selectionStart||v.length,n=clean(v.slice(0,p)).length,c=clean(v).slice(0,6),f=fmt(c);inp.value=f;
if(document.activeElement===inp){var i=0,k=0;while(i<f.length&&k<n){if(f[i]!=='-')k++;i++;}try{inp.setSelectionRange(i,i);}catch(_){}}
if(root.getAttribute('data-s')==='err'&&valid(c))setErr('');}
function setErr(m){e.textContent=m;if(m){root.setAttribute('data-s','err');inp.setAttribute('aria-invalid','true');}else{root.removeAttribute('data-s');inp.removeAttribute('aria-invalid');}}
function nlDate(d){return DAG[d.getDay()]+' '+d.getDate()+' '+MND[d.getMonth()]+' '+d.getFullYear();}
function hash(s){var x=7;for(var i=0;i<s.length;i++)x=(x*31+s.charCodeAt(i))>>>0;return x;}
function lookup(c){if(NOTFOUND[c])return null;var f=FIX[c],x=hash(c);if(!f)f=[x%CARS.length,KLEUR[x%KLEUR.length],2010+x%14,(x%720)-60];
var car=CARS[f[0]],apk=new Date();apk.setDate(apk.getDate()+f[3]);return {car:car,kleur:f[1],jaar:f[2],apk:apk,dagen:f[3]};}
function show(c){var r=lookup(c),plate=fmt(c);
if(!r){res.innerHTML='<div class="knl__nf"><b>Geen voertuig gevonden bij '+plate+'.</b><br>Controleer het kenteken of vul merk en model zelf in.<br><button type="button" class="knl__new">Ander kenteken</button></div>';return;}
var st=r.dagen<0?['is-bad','Verlopen']:r.dagen<60?['is-warn','Verloopt binnenkort']:['is-ok','Geldig'];
res.innerHTML='<div class="knl__card"><div class="knl__car"><b>'+r.car[0]+'</b><span>'+r.car[1]+' · '+r.car[2]+'</span></div><dl class="knl__dl"><div><dt>Kleur</dt><dd>'+r.kleur+'</dd></div><div><dt>Bouwjaar</dt><dd>'+r.jaar+'</dd></div><div><dt>APK tot</dt><dd>'+nlDate(r.apk)+'<br><span class="knl__pill '+st[0]+'">'+st[1]+'</span></dd></div></dl><p class="knl__src">Voorbeelddata. In productie uit RDW Open Data.</p></div>';}
inp.addEventListener('input',apply);
form.addEventListener('submit',function(ev){ev.preventDefault();var c=clean(inp.value);
if(!c){setErr('Vul een kenteken in, bijvoorbeeld GH-482-T');inp.focus();res.innerHTML='';return;}
if(c.length<6){setErr('Een kenteken heeft 6 letters en cijfers, je hebt er nu '+c.length);inp.focus();res.innerHTML='';return;}
if(!valid(c)){setErr('Deze volgorde van letters en cijfers bestaat niet als Nederlands kenteken');inp.focus();res.innerHTML='';return;}
setErr('');btn.setAttribute('aria-busy','true');btn.textContent='Zoeken';res.setAttribute('aria-busy','true');res.innerHTML='<div class="knl__sk" aria-label="Kenteken wordt opgezocht"><i></i><i></i><i></i></div>';
setTimeout(function(){btn.removeAttribute('aria-busy');btn.textContent='Check';res.removeAttribute('aria-busy');show(c);},750);});
h.addEventListener('click',function(ev){var b=ev.target.closest('button');if(!b)return;inp.value=fmt(b.dataset.k);setErr('');form.requestSubmit?form.requestSubmit():form.dispatchEvent(new Event('submit',{cancelable:true}));});
res.addEventListener('click',function(ev){if(ev.target.closest('.knl__new')){inp.value='';res.innerHTML='';inp.focus();}});
}
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 →