Vraagveld voor een AI-assistent Nieuw
Rustig vraagveld voor een assistent op de eigen site: een tekstvak dat meegroeit, drie voorbeeldvragen die je met één klik invult, een verzendknop die pas actief wordt als er tekst staat, Enter om te versturen en Shift+Enter voor een nieuwe regel. Het antwoord verschijnt onder de vraag met de bronpagina erbij en een duidelijke grens (bel bij twijfel). Geen fonkelende sterretjes of verlopen: het hoort bij de site, niet bij de AI. Voorbeeld voor een fysiotherapiepraktijk; de antwoorden zijn hier vast ingesteld.
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.
<!-- Vraagveld voor een AI-assistent · NedDev · eigen werk. -->
<div class="jouw-container">
<div class="aiv"><div class="aiv__in">
<form class="aiv__form">
<label class="aiv__lab" for="aiv-t">Vraag het de praktijkassistent</label>
<p class="aiv__sub" id="aiv-s">Fysiotherapie Leiden-Noord. Antwoorden komen uit de informatie op deze site.</p>
<div class="aiv__qa" hidden><p class="aiv__you"></p><div class="aiv__ans" aria-live="polite"></div></div>
<div class="aiv__box">
<textarea class="aiv__t" id="aiv-t" rows="1" aria-describedby="aiv-s aiv-k" placeholder="Stel je vraag over behandeling, vergoeding of afspraken"></textarea>
<button class="aiv__send" type="submit" disabled><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M10 16V4M5 9l5-5 5 5"/></svg><span class="aiv__vh">Vraag versturen</span></button>
</div>
<p class="aiv__keys" id="aiv-k">Enter om te versturen, Shift+Enter voor een nieuwe regel</p>
<div class="aiv__ex" role="group" aria-label="Voorbeeldvragen">
<button type="button">Wordt fysio vergoed uit mijn basisverzekering?</button>
<button type="button">Heb ik een verwijzing van de huisarts nodig?</button>
<button type="button">Kan ik ook 's avonds terecht?</button>
</div>
</form>
</div></div>
</div>/* Vraagveld voor een AI-assistent · NedDev · eigen werk. */
.aiv{position:absolute;inset:0;overflow:auto;display:flex;padding:12px;box-sizing:border-box;background:#f4f3f1;font-family:'Switzer',sans-serif;color:#0a0a0a}
.aiv *,.aiv *::before,.aiv *::after{box-sizing:border-box}
.aiv [hidden]{display:none!important}
.aiv__in{margin:auto;width:100%;max-width:420px}
.aiv__lab{display:block;font-size:15px;font-weight:700}
.aiv__sub{margin:2px 0 8px;font-size:12.5px;color:#4a4a4a;line-height:1.4}
.aiv__box{display:flex;align-items:flex-end;gap:6px;padding:6px 6px 6px 12px;background:#fff;border:1px solid #8c8c8c;border-radius:8px;transition:border-color .15s,box-shadow .15s}
.aiv__box:hover{border-color:#0a0a0a}
.aiv__box:focus-within{border-color:#0a0a0a;box-shadow:0 0 0 3px rgba(245,72,15,.35)}
.aiv__t{flex:1;min-width:0;min-height:32px;max-height:96px;padding:6px 0;border:0;outline:0;resize:none;background:none;font:400 14px/1.45 'Switzer',sans-serif;color:#0a0a0a;overflow-y:auto}
@supports (field-sizing:content){.aiv__t{field-sizing:content}}
.aiv__t::placeholder{color:#6b6b6b}
.aiv__send{flex:none;width:34px;height:34px;display:grid;place-items:center;border:0;border-radius:4px;background:#0a0a0a;color:#fff;cursor:pointer;transition:background-color .15s,opacity .15s}
.aiv__send svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.aiv__send:hover:not(:disabled){background:#2a2a2a}
.aiv__send:disabled{background:#d9d6d0;color:#6b6b6b;cursor:not-allowed}
.aiv__send:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.aiv__vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.aiv__send{position:relative}
.aiv__keys{margin:4px 0 0;font-size:12px;color:#6b6b6b}
.aiv__ex{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
.aiv__ex button{min-height:28px;padding:4px 9px;border:1px solid rgba(10,10,10,.22);border-radius:4px;background:#fff;font:500 12.5px 'Switzer',sans-serif;color:#0a0a0a;text-align:left;cursor:pointer;transition:border-color .15s}
.aiv__ex button:hover{border-color:#0a0a0a}
.aiv__ex button:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.aiv__qa{margin-bottom:8px;font-size:13px;line-height:1.45}
.aiv__you{margin:0 0 6px;padding:7px 10px;background:#0a0a0a;color:#fff;border-radius:8px;margin-left:15%}
.aiv__ans{padding:8px 10px;background:#fff;border:1px solid rgba(10,10,10,.12);border-radius:8px;min-height:36px}
.aiv__ans p{margin:0}
.aiv__src{margin-top:5px!important;font-size:12px;color:#4a4a4a}
.aiv__src a{color:#0a0a0a;text-underline-offset:2px}
.aiv__wait{display:flex;align-items:center;gap:8px;color:#4a4a4a}
.aiv__wait i{display:block;width:44px;height:3px;background:linear-gradient(90deg,#d9d6d0 0 30%,#0a0a0a 30% 60%,#d9d6d0 60%);background-size:200% 100%;border-radius:2px;animation:aiv-l 1.1s linear infinite}
@keyframes aiv-l{from{background-position:100% 0}to{background-position:-100% 0}}
.aiv__ans.is-new{animation:aiv-f .35s ease}
@keyframes aiv-f{from{opacity:.2}to{opacity:1}}
@media (prefers-reduced-motion:reduce){.aiv *{transition:none!important;animation:none!important}}// Vraagveld voor een AI-assistent · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.aiv');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('.aiv__form'),t=w.querySelector('.aiv__t'),send=w.querySelector('.aiv__send'),qa=w.querySelector('.aiv__qa'),you=w.querySelector('.aiv__you'),ans=w.querySelector('.aiv__ans'),ex=w.querySelector('.aiv__ex'),busy=false;
var fit=!(window.CSS&&CSS.supports&&CSS.supports('field-sizing','content'));
function grow(){if(!fit)return;t.style.height='auto';t.style.height=Math.min(t.scrollHeight,96)+'px';}
function upd(){send.disabled=busy||!t.value.trim();grow();}
t.addEventListener('input',upd);
t.addEventListener('keydown',function(e){if(e.key==='Enter'&&!e.shiftKey&&!e.isComposing){e.preventDefault();if(!send.disabled)f.requestSubmit?f.requestSubmit():f.dispatchEvent(new Event('submit',{cancelable:true}));}});
ex.querySelectorAll('button').forEach(function(b){b.addEventListener('click',function(){t.value=b.textContent;upd();t.focus();});});
var A=[[/vergoed|verzeker|kost|prijs/i,'De basisverzekering vergoedt fysiotherapie meestal niet; alleen bij bepaalde chronische aandoeningen vanaf de 21e behandeling. Met een aanvullende verzekering krijg je vaak 9 tot 27 behandelingen per jaar vergoed. Een losse behandeling kost bij ons \u20ac\u00a043,50.','Vergoedingen'],
[/verwijz|huisarts/i,'Nee, je kunt zonder verwijzing bij ons terecht. Bij het eerste bezoek doen we een korte screening. Sommige verzekeraars vragen wel om een verwijzing voor vergoeding, check dat in je polis.','Aanmelden'],
[/avond|laat|weekend|zaterdag|open/i,'Ja, op dinsdag en donderdag behandelen we tot 21:00. Op zaterdag zijn we open van 9:00 tot 13:00. Een afspraak maak je online of via 071 123 4567.','Openingstijden']];
f.addEventListener('submit',function(e){e.preventDefault();var v=t.value.trim();if(!v||busy)return;busy=true;
you.textContent=v;qa.hidden=false;ex.hidden=true;ans.classList.remove('is-new');ans.innerHTML='<p class="aiv__wait"><i aria-hidden="true"></i>Even zoeken in onze informatie</p>';t.value='';upd();
var hit=A.filter(function(a){return a[0].test(v);})[0];
setTimeout(function(){busy=false;ans.classList.add('is-new');
ans.innerHTML=hit?'<p>'+hit[1]+'</p><p class="aiv__src">Bron: <a href="#ai-vraagveld">'+hit[2]+'</a>. Twijfel je? Bel de praktijk.</p>':'<p>Daar kan ik geen betrouwbaar antwoord op geven. Bel de praktijk op 071 123 4567 of mail naar info@voorbeeld.nl, dan helpen we je persoonlijk.</p>';
upd();t.focus();},1100);});
upd();
}
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 →