Telefoonveld met landcode New
Phone field with a country picker (NL, BE, DE and more) that formats as you type, recognises the number type (mobile, landline with city) and validates. Pasting a +32 number switches the country. Native select plus small JS; in production use libphonenumber-js (MIT) for all countries.
Probeer
We bellen alleen over je afspraak.
Opgeslagen als
How to use it
- Paste the HTML where the forms & inputs 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.
<!-- Telefoonveld met landcode · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="tlc"><div class="tlc__in"><div class="tlc__card">
<div class="tlc__demo" role="group" aria-label="Voorbeelden invullen"><span class="tlc__demo-l">Probeer</span><button type="button" data-v="0612345678" data-c="NL">06-nummer</button><button type="button" data-v="0101234567" data-c="NL">Vast 010</button><button type="button" data-v="+32470123456">Belgisch</button><button type="button" data-v="06123" data-c="NL">Fout</button></div>
<label class="tlc__l" for="tlc-n">Telefoonnummer</label>
<div class="tlc__grp">
<span class="tlc__sw"><select class="tlc__sel" aria-label="Landcode"><option value="NL" selected>NL +31</option><option value="BE">BE +32</option><option value="DE">DE +49</option><option value="FR">FR +33</option><option value="GB">GB +44</option><option value="ES">ES +34</option><option value="TR">TR +90</option><option value="MA">MA +212</option><option value="SR">SR +597</option></select><svg viewBox="0 0 10 6" aria-hidden="true"><path d="M1 1l4 4 4-4"/></svg></span>
<input class="tlc__i" id="tlc-n" type="tel" inputmode="tel" autocomplete="tel-national" placeholder="06 1234 5678" aria-describedby="tlc-e tlc-s">
<span class="tlc__badge" aria-hidden="true"></span>
</div>
<p class="tlc__e" id="tlc-e"></p>
<p class="tlc__s" id="tlc-s">We bellen alleen over je afspraak.</p>
<p class="tlc__out" hidden>Opgeslagen als <code></code></p>
</div></div></div>
</div>/* Telefoonveld met landcode · NedDev · eigen werk. */
.tlc [hidden]{display:none!important}
.tlc{position:absolute;inset:0;overflow:auto;display:flex;padding:14px;box-sizing:border-box;background:#f4f3f1;container-type:inline-size;font-family:'Switzer',system-ui,sans-serif;color:#0a0a0a;scrollbar-width:thin}
.tlc *,.tlc *::before,.tlc *::after{box-sizing:border-box}
.tlc__in{margin:auto;width:100%;max-width:420px}
.tlc__card{background:#fff;border:1px solid rgba(10,10,10,.12);border-radius:6px;padding:14px}
.tlc__demo{display:flex;flex-wrap:wrap;align-items:center;gap:5px;margin-bottom:12px;font:500 10px 'JetBrains Mono',monospace;letter-spacing:.06em;text-transform:uppercase}
.tlc__demo-l{color:#5a5a5a}
.tlc__demo button{font:inherit;letter-spacing:inherit;text-transform:inherit;padding:4px 8px;border:1px solid rgba(10,10,10,.25);background:#fff;color:#0a0a0a;border-radius:100px;cursor:pointer;transition:border-color .15s}
.tlc__demo button:hover{border-color:#0a0a0a}
.tlc__l{display:block;font-size:13px;font-weight:600;margin-bottom:5px}
.tlc__grp{position:relative;display:flex;border:1px solid #8c8c8c;border-radius:4px;background:#fff;transition:border-color .15s,box-shadow .15s}
.tlc__grp:hover{border-color:#0a0a0a}
.tlc__grp:focus-within{border-color:#0a0a0a;box-shadow:0 0 0 3px rgba(245,72,15,.35)}
.tlc[data-s="err"] .tlc__grp{border-color:#B42318}
.tlc[data-s="ok"] .tlc__grp{border-color:#146C43}
.tlc__sw{position:relative;flex:none;border-right:1px solid rgba(10,10,10,.15)}
.tlc__sel{appearance:none;-webkit-appearance:none;height:100%;font:600 13px 'JetBrains Mono',monospace;color:#0a0a0a;background:#faf9f7;border:0;border-radius:3px 0 0 3px;padding:0 26px 0 10px;cursor:pointer}
.tlc__sel:focus-visible{outline:2px solid #F5480F;outline-offset:-2px}
.tlc__sw svg{position:absolute;right:9px;top:50%;width:10px;height:6px;margin-top:-3px;fill:none;stroke:#0a0a0a;stroke-width:1.6;pointer-events:none}
.tlc__i{flex:1;min-width:0;font:500 15px/1.4 'Switzer',system-ui,sans-serif;letter-spacing:.02em;color:#0a0a0a;background:transparent;border:0;padding:10px 11px;outline:none}
.tlc__i::placeholder{color:#767676}
.tlc__badge{align-self:center;flex:none;margin-right:8px;font:600 10px 'JetBrains Mono',monospace;letter-spacing:.06em;text-transform:uppercase;padding:3px 7px;border-radius:100px;background:#e8f3ec;color:#0f5535;white-space:nowrap;max-width:46%;overflow:hidden;text-overflow:ellipsis}
.tlc__badge:empty{display:none}
@container (max-width:380px){.tlc__badge{display:none}}
.tlc__e{margin:5px 0 0;font-size:12.5px;color:#B42318;line-height:1.35}
.tlc__e:empty{display:none}
.tlc__s{margin:5px 0 0;font-size:12.5px;color:#5a5a5a}
.tlc__out{margin:8px 0 0;font-size:12px;color:#5a5a5a}
.tlc__out code{font:600 12px 'JetBrains Mono',monospace;color:#0a0a0a;background:#f4f3f1;padding:2px 6px;border-radius:3px}
.tlc__demo button:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
@media (prefers-reduced-motion:reduce){.tlc *{transition:none!important}}// Telefoonveld met landcode · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
root=root.querySelector('.tlc')||root;
var sfx='-'+Math.random().toString(36).slice(2,7);['tlc-n','tlc-e','tlc-s'].forEach(function(o){var el=root.querySelector('#'+o);if(el)el.id=o+sfx;});
var sel=root.querySelector('.tlc__sel'),inp=root.querySelector('.tlc__i'),badge=root.querySelector('.tlc__badge'),e=root.querySelector('.tlc__e'),s=root.querySelector('.tlc__s'),out=root.querySelector('.tlc__out'),code=out.querySelector('code');
root.querySelector('.tlc__l').setAttribute('for',inp.id);inp.setAttribute('aria-describedby',e.id+' '+s.id);
var CC={NL:'31',BE:'32',DE:'49',FR:'33',GB:'44',ES:'34',TR:'90',MA:'212',SR:'597'},TRUNK={NL:1,BE:1,DE:1,FR:1,GB:1,TR:1,MA:1};
var PH={NL:'06 1234 5678',BE:'0470 12 34 56',DE:'030 1234567',FR:'06 12 34 56 78',GB:'07700 900123',ES:'612 34 56 78',TR:'0532 123 45 67',MA:'0612 345 678',SR:'712 3456'};
var AREA={'010':'Rotterdam','013':'Tilburg','015':'Delft','020':'Amsterdam','023':'Haarlem','024':'Nijmegen','026':'Arnhem','030':'Utrecht','033':'Amersfoort','035':'Hilversum','036':'Almere','038':'Zwolle','040':'Eindhoven','043':'Maastricht','045':'Heerlen','046':'Sittard','050':'Groningen','053':'Enschede','055':'Apeldoorn','058':'Leeuwarden','070':'Den Haag','071':'Leiden','072':'Alkmaar','073':'Den Bosch','074':'Hengelo','075':'Zaandam','076':'Breda','077':'Venlo','078':'Dordrecht','079':'Zoetermeer','085':'','088':'','091':''};
var touched=false;
function groups(d,g){var o=[],i=0;g.forEach(function(n){if(i<d.length){o.push(d.slice(i,i+n));i+=n;}});if(i<d.length)o.push(d.slice(i));return o.join(' ');}
function fmt(c,d){if(c==='NL'){if(/^06/.test(d))return groups(d,[2,4,4]);if(AREA.hasOwnProperty(d.slice(0,3)))return groups(d,[3,3,4]);return groups(d,[4,3,3]);}
if(c==='BE'){if(/^04[5-9]/.test(d))return groups(d,[4,2,2,2]);if(/^0[2349]/.test(d))return groups(d,[2,3,2,2]);return groups(d,[3,2,2,2]);}
return groups(d,[3,3,3,3,3]);}
function info(c,d){if(c==='NL'){if(/^0(800|90)/.test(d))return {err:'Servicenummers zoals 0800 en 0900 kunnen we niet terugbellen'};if(d.length<10)return {err:'Nog '+(10-d.length)+(10-d.length===1?' cijfer':' cijfers')+', een Nederlands nummer heeft er 10'};if(d.length>10)return {err:'Eén of meer cijfers te veel, een Nederlands nummer heeft er 10'};
if(!/^0[1-9]/.test(d))return {err:'Dit nummer bestaat niet in Nederland'};if(/^06/.test(d))return /^06[1-9]/.test(d)?{t:'Mobiel'}:{err:'Dit 06-nummer klopt niet'};var a=AREA[d.slice(0,3)];return {t:a?'Vast · '+a:(a===''?'Vast · landelijk':'Vast')};}
if(c==='BE'){if(/^04[5-9]/.test(d))return d.length===10?{t:'Mobiel'}:{err:'Een Belgisch mobiel nummer heeft 10 cijfers, bijvoorbeeld 0470 12 34 56'};return d.length===9&&/^0[1-9]/.test(d)?{t:'Vast'}:{err:'Een Belgisch vast nummer heeft 9 cijfers, bijvoorbeeld 02 123 45 67'};}
return d.length>=6&&d.length<=13?{t:''}:{err:'Dit nummer lijkt te kort of te lang'};}
function national(c,d){if(TRUNK[c]&&d&&d[0]!=='0')d='0'+d;return d;}
function e164(c,d){return '+'+CC[c]+(TRUNK[c]?d.replace(/^0/,''):d);}
function digitsBefore(v,p){return v.slice(0,p).replace(/\D/g,'').length;}
function apply(keepCaret){var v=inp.value,p=inp.selectionStart||v.length,db=digitsBefore(v,p);
var m=v.replace(/[^\d+]/g,'');if(/^(\+|00)/.test(m)){var raw=m.replace(/^\+|^00/,'');for(var k in CC){if(raw.indexOf(CC[k])===0){sel.value=k;raw=raw.slice(CC[k].length);db=Math.max(0,db-CC[k].length-(m[0]==='0'?2:0));var d0=national(k,raw);if(d0!==raw)db++;render(d0,keepCaret,db);return;}}}
var d=v.replace(/\D/g,'');var d2=national(sel.value,d);if(d2!==d&&d)db++;render(d2,keepCaret,db);}
function render(d,keepCaret,db){var c=sel.value,f=fmt(c,d);inp.value=f;inp.placeholder=PH[c];
if(keepCaret&&document.activeElement===inp){var i=0,n=0;while(i<f.length&&n<db){if(/\d/.test(f[i]))n++;i++;}try{inp.setSelectionRange(i,i);}catch(_){}}
var r=d?info(c,d):{err:''};badge.textContent=r.t||'';
var show=touched||!!(r.err&&/te veel|Servicenummer|bestaat niet/.test(r.err));
if(!d){root.removeAttribute('data-s');e.textContent='';inp.removeAttribute('aria-invalid');out.hidden=true;s.textContent='We bellen alleen over je afspraak.';return;}
if(r.err){out.hidden=true;s.textContent='We bellen alleen over je afspraak.';if(show){root.setAttribute('data-s','err');e.textContent=r.err;inp.setAttribute('aria-invalid','true');}else{root.removeAttribute('data-s');e.textContent='';inp.removeAttribute('aria-invalid');}return;}
root.setAttribute('data-s','ok');e.textContent='';inp.removeAttribute('aria-invalid');out.hidden=false;code.textContent=e164(c,d);s.textContent=(r.t?r.t+' nummer':'Nummer')+' herkend.';}
inp.addEventListener('input',function(){apply(true);});
inp.addEventListener('blur',function(){if(inp.value)touched=true;apply(false);});
sel.addEventListener('change',function(){apply(false);});
root.querySelector('.tlc__demo').addEventListener('click',function(ev){var b=ev.target.closest('button');if(!b)return;if(b.dataset.c)sel.value=b.dataset.c;inp.value=b.dataset.v;touched=true;apply(false);});
apply(false);
}
init(document.querySelector('.jouw-container'));
More forms & inputs
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 →