Créer un widget de validation du numéro KVK en JavaScript
Tutoriel pas à pas pour créer un widget intégrable de recherche par numéro KVK en JavaScript : événements, accessibilité et personnalisation CSS.
Un widget de validation du numéro KVK permet à vos utilisateurs de saisir un numéro de la chambre de commerce néerlandaise et de voir instantanément les données de l’entreprise correspondante. Dans ce tutoriel, nous en construisons un à partir de zéro avec le widget KVKBase, puis nous voyons comment le personnaliser et l’étendre pour votre propre application.
Démarrage rapide : utiliser le widget KVKBase
Le chemin le plus rapide vers un widget de recherche KVK fonctionnel est le composant KVKBase prêt à l’emploi. Ajoutez une seule balise script et un élément personnalisé à votre page :
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<title>KVK Lookup</title>
</head>
<body>
<h1>Zoek een bedrijf</h1>
<script
src="https://widget.kvkbase.nl/kvk-lookup.js"
data-api-key="YOUR_API_KEY"
></script>
<kvk-lookup
placeholder="KVK-nummer invoeren"
lang="nl"
></kvk-lookup>
</body>
</html>
C’est tout ce qu’il faut pour un widget de recherche pleinement fonctionnel. Le composant gère d’emblée la validation de la saisie, les appels d’API, les états de chargement et l’affichage des résultats.
Attributs de données
Le widget accepte plusieurs attributs de données pour sa configuration :
<kvk-lookup
placeholder="Voer een KVK-nummer in"
lang="nl"
show-details="true"
auto-submit="false"
theme="light"
></kvk-lookup>
| Attribut | Valeur par défaut | Description |
|---|---|---|
placeholder | ”KVK nummer” | Texte indicatif du champ de saisie |
lang | ”nl” | Langue : “nl” ou “en” |
show-details | ”true” | Afficher les données de l’entreprise après la recherche |
auto-submit | ”true” | Lancer automatiquement la recherche dès que 8 chiffres sont saisis |
theme | ”light” | Thème de couleurs : “light” ou “dark” |
Gestion des événements
La vraie puissance du widget vient de son système d’événements. Vous pouvez écouter des événements pour réagir lorsqu’une entreprise est trouvée, lorsqu’une erreur survient ou lorsque l’utilisateur vide le champ.
kvkbase:found
Déclenché lorsqu’une entreprise valide est trouvée :
const widget = document.querySelector('kvk-lookup');
widget.addEventListener('kvkbase:found', (event) => {
const company = event.detail;
console.log('Company found:', company.tradeName);
console.log('KVK:', company.kvkNumber);
console.log('Address:', company.address);
console.log('Active:', company.isActive);
});
L’objet event.detail contient le profil complet de l’entreprise :
{
kvkNumber: "12345678",
tradeName: "Example BV",
legalForm: "Besloten Vennootschap",
address: {
street: "Keizersgracht",
houseNumber: "100",
postalCode: "1015AA",
city: "Amsterdam"
},
sbiCodes: [
{ code: "6201", description: "Software development" }
],
isActive: true,
vatNumber: "NL123456789B01"
}
kvkbase:error
Déclenché lorsqu’une recherche échoue :
widget.addEventListener('kvkbase:error', (event) => {
const error = event.detail;
switch (error.code) {
case 'NOT_FOUND':
showMessage('No company found with this KVK number.');
break;
case 'INVALID_FORMAT':
showMessage('Please enter a valid 8-digit KVK number.');
break;
case 'RATE_LIMITED':
showMessage('Too many requests. Please try again shortly.');
break;
default:
showMessage('Something went wrong. Please try again.');
}
});
kvkbase:clear
Déclenché lorsque l’utilisateur vide le champ :
widget.addEventListener('kvkbase:clear', () => {
// Réinitialiser les champs de formulaire remplis automatiquement
document.getElementById('company-name').value = '';
document.getElementById('address').value = '';
});
Remplir automatiquement les champs de formulaire
Le cas d’usage le plus courant est le remplissage automatique d’un formulaire d’inscription ou de paiement :
<form id="registration-form">
<label>KVK Nummer</label>
<kvk-lookup id="kvk-widget"></kvk-lookup>
<label>Bedrijfsnaam</label>
<input type="text" id="company-name" readonly>
<label>Adres</label>
<input type="text" id="address" readonly>
<label>Postcode</label>
<input type="text" id="postal-code" readonly>
<label>Plaats</label>
<input type="text" id="city" readonly>
<label>BTW-nummer</label>
<input type="text" id="vat-number" readonly>
<button type="submit">Registreren</button>
</form>
<script>
document.getElementById('kvk-widget')
.addEventListener('kvkbase:found', (event) => {
const c = event.detail;
document.getElementById('company-name').value = c.tradeName;
document.getElementById('address').value =
`${c.address.street} ${c.address.houseNumber}`;
document.getElementById('postal-code').value = c.address.postalCode;
document.getElementById('city').value = c.address.city;
document.getElementById('vat-number').value = c.vatNumber || '';
});
</script>
Personnalisation CSS
Le widget utilise le Shadow DOM pour encapsuler ses styles, mais il expose des propriétés personnalisées CSS pour le thème :
kvk-lookup {
--kvk-primary-color: #2563eb;
--kvk-border-color: #d1d5db;
--kvk-border-radius: 8px;
--kvk-font-family: 'Inter', sans-serif;
--kvk-font-size: 14px;
--kvk-input-padding: 12px 16px;
--kvk-background: #ffffff;
--kvk-text-color: #111827;
--kvk-error-color: #dc2626;
--kvk-success-color: #16a34a;
}
Pour le mode sombre :
@media (prefers-color-scheme: dark) {
kvk-lookup {
--kvk-background: #1f2937;
--kvk-text-color: #f9fafb;
--kvk-border-color: #4b5563;
}
}
Points d’attention en matière d’accessibilité
Un widget bien conçu doit être accessible. Le widget KVKBase inclut plusieurs fonctions d’accessibilité par défaut, mais voici des points importants à garder en tête lors de l’intégration :
Libellés et ARIA
Associez toujours un libellé au widget :
<label for="kvk-input">KVK Nummer</label>
<kvk-lookup id="kvk-input" aria-label="KVK nummer opzoeken"></kvk-lookup>
Navigation au clavier
Le widget prend en charge la navigation complète au clavier :
- Tab pour placer le focus sur le champ
- Entrée pour lancer la recherche
- Échap pour effacer les résultats
- Les flèches pour naviguer dans les suggestions de recherche
Annonces pour les lecteurs d’écran
Lorsqu’une entreprise est trouvée ou qu’une erreur survient, le widget utilise des régions aria-live pour annoncer le résultat aux lecteurs d’écran. Vous n’avez rien à ajouter pour cela : cela fonctionne d’emblée.
États d’erreur
Les messages d’erreur sont associés au champ via aria-describedby, de sorte que les lecteurs d’écran les annoncent dans leur contexte.
Créer un widget personnalisé
Si vous avez besoin d’un contrôle total sur l’interface, vous pouvez créer votre propre widget en utilisant directement l’API KVKBase :
class CustomKvkLookup extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
this.shadowRoot.querySelector('input')
.addEventListener('input', this.handleInput.bind(this));
}
async handleInput(e) {
const value = e.target.value.replace(/\D/g, '');
if (value.length !== 8) return;
const statusEl = this.shadowRoot.querySelector('.status');
statusEl.textContent = 'Searching...';
try {
const res = await fetch(
`https://api.kvkbase.nl/api/v1/lookup/${value}`,
{ headers: { 'Authorization': `Bearer ${this.getAttribute('api-key')}` } }
);
const data = await res.json();
this.dispatchEvent(new CustomEvent('kvkbase:found', { detail: data }));
statusEl.textContent = data.tradeName;
} catch {
this.dispatchEvent(new CustomEvent('kvkbase:error', {
detail: { code: 'NETWORK_ERROR' }
}));
statusEl.textContent = 'Lookup failed';
}
}
render() {
this.shadowRoot.innerHTML = `
<style>
:host { display: block; }
input { width: 100%; padding: 8px 12px; font-size: 16px; }
.status { margin-top: 8px; color: #666; }
</style>
<input type="text" maxlength="8" placeholder="KVK nummer"
aria-label="KVK nummer">
<div class="status" aria-live="polite"></div>
`;
}
}
customElements.define('custom-kvk-lookup', CustomKvkLookup);
En résumé
Que vous utilisiez le widget KVKBase prêt à l’emploi ou que vous construisiez le vôtre, les ingrédients clés sont les mêmes : une validation propre de la saisie, des appels d’API réactifs, une gestion claire des événements et un balisage accessible. Le widget KVKBase vous offre tout cela d’emblée, tandis que l’API vous permet de construire exactement l’interface souhaitée.
Commencez par le widget pour une intégration rapide, puis personnalisez-le avec les propriétés CSS et les écouteurs d’événements à mesure que vos besoins évoluent.