De blauwe balk werd alleen door de pijltjes verzet: er was een li.active-stijl maar geen enkele hover- of mousemove-handler, dus wie met de muis over de lijst ging stond nergens op. Nu verzet mousemove dezelfde active-regel als het toetsenbord. Bewust geen mouseover, want een stilliggende muis boven de lijst zou dan de pijltjes blijven tegenwerken. Daarbovenop een generiek haakje om suggesties op te ruimen, zoals de adresbalk van een browser dat doet. Een optie of optgroup met data-removable is met Delete te wissen: het script haalt zelf niets weg maar stuurt een select-search:remove-event met value, label en index, en wie de lijst bezit past de opties aan. Geen kruisje per regel: dat neemt plek in en wie met de muis op een regel staat wil die kiezen, niet weggooien. Delete vuurt alleen zolang er niets getypt is, anders blijft het een gewone teksttoets. Die vraag werd eerst met input.value beantwoord, en dat is niet de zoekterm: bij een open lijst zonder typwerk staat daar het gekozen label in, geselecteerd en klaar om over te typen. Delete deed dus niets in precies de gewone situatie. De zoekterm zit nu in een eigen variabele, en die lost hetzelfde stille probleem op in resync, die de open lijst zou dichtfilteren op een label dat de gebruiker nooit intypte. Na een herbouw van de opties blijft de balk staan waar hij stond, geklemd op de laatste regel, zodat je meerdere regels achter elkaar kan wissen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
133 lines
4.9 KiB
HTML
133 lines
4.9 KiB
HTML
<!doctype html>
|
|
<html lang="nl">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>select-search fixture</title>
|
|
<style>
|
|
body{font:13px/1.5 system-ui,-apple-system,"Segoe UI",sans-serif;margin:24px;color:#111}
|
|
table{border-spacing:0 6px}
|
|
td:first-child{padding-right:24px}
|
|
select{width:400px}
|
|
#uit{margin-top:20px;padding:8px;background:#f2f5fb;border:1px solid #cbd8ee;white-space:pre-wrap}
|
|
.bar{background:#eaf1fb;padding:8px;margin:-24px -24px 20px}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="bar">Testpagina, bootst de werk-app na</div>
|
|
<form id="f">
|
|
<label><input type="checkbox" id="incl"> Inclusief niet-raamcontractartikelen</label>
|
|
<table>
|
|
<tr><td><label for="lev">Leverancier</label></td>
|
|
<td><select id="lev" name="leverancier"></select></td></tr>
|
|
<tr><td><label for="fab">Fabricaat</label></td>
|
|
<td><select id="fab" name="fabricaat" data-placeholder="fabricaat"></select></td></tr>
|
|
<tr><td><label for="groep">Met groepen</label></td>
|
|
<td><select id="groep" name="groep"></select></td></tr>
|
|
<tr><td><label for="klein">Klein menu</label></td>
|
|
<td><select id="klein" name="klein">
|
|
<option value="">--</option><option>Ja</option><option>Nee</option>
|
|
</select></td></tr>
|
|
</table>
|
|
<button type="submit">Verzenden</button>
|
|
</form>
|
|
<div id="uit">nog niets verzonden</div>
|
|
|
|
<script>
|
|
var VOOR = ['Restaurant','Bakkerij','Groothandel','Technische Dienst','Installatiebedrijf',
|
|
'Drukkerij','Transport','Bouwbedrijf','Schoonmaak','Catering','Labo','Apotheek',
|
|
'Garage','Kwekerij','Slagerij','Boekhandel','Meubelmakerij','Elektro'];
|
|
var NAAM = ['Poule & Poulette','Van den Berghe','De Smet','Janssens','Peeters','Maertens',
|
|
'Vermeulen','Claeys','De Vos','Willems','Lemmens','Coppens','Declercq','Genée',
|
|
'Vanhoutte','Segers','Wouters','Dhondt','Vandenbroucke','Storms'];
|
|
var VORM = ['B.V.','N.V.','BVBA','VZW','Comm.V.','& Zonen'];
|
|
|
|
function maak(n, offset){
|
|
var out = [];
|
|
for (var i = 0; i < n; i++) {
|
|
var v = VOOR[(i + offset) % VOOR.length];
|
|
var m = NAAM[(i * 7 + offset) % NAAM.length];
|
|
var s = VORM[(i * 3 + offset) % VORM.length];
|
|
out.push({v: 'ID' + (1000 + i + offset), t: v + ' ' + m + ' ' + s + ' (' + (1000 + i + offset) + ')'});
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function vul(sel, n, offset){
|
|
var huidig = sel.value;
|
|
sel.innerHTML = '';
|
|
var leeg = document.createElement('option');
|
|
leeg.value = ''; leeg.textContent = '';
|
|
sel.appendChild(leeg);
|
|
maak(n, offset).forEach(function(o){
|
|
var e = document.createElement('option');
|
|
e.value = o.v; e.textContent = o.t;
|
|
sel.appendChild(e);
|
|
});
|
|
sel.value = huidig;
|
|
}
|
|
|
|
// Select met optgroups: recent bovenaan, daarna de rest, plus een optie zonder groep die
|
|
// bovenaan los blijft staan. Labels lang genoeg om af te kappen.
|
|
function vulGroepen(sel){
|
|
sel.innerHTML = '';
|
|
var leeg = document.createElement('option');
|
|
leeg.value = ''; leeg.textContent = 'leverancier';
|
|
sel.appendChild(leeg);
|
|
var blokken = [
|
|
['recent', maak(3, 300)],
|
|
['alle leveranciers', maak(60, 700)]
|
|
];
|
|
blokken.forEach(function(blok){
|
|
var g = document.createElement('optgroup');
|
|
g.label = blok[0];
|
|
// Alleen recent mag met Delete uitgedund worden. Zo is de vlag hier ook echt getest.
|
|
if (blok[0] === 'recent') g.dataset.removable = '1';
|
|
blok[1].forEach(function(o){
|
|
var e = document.createElement('option');
|
|
e.value = o.v; e.textContent = o.t;
|
|
g.appendChild(e);
|
|
});
|
|
sel.appendChild(g);
|
|
});
|
|
}
|
|
vulGroepen(document.getElementById('groep'));
|
|
|
|
// De host beslist wat verwijderen betekent. Hier: de optie gaat uit recent en verhuist naar de
|
|
// tweede groep, net als het echte script met zijn recente budgetcodes doet.
|
|
document.getElementById('groep').addEventListener('select-search:remove', function(e){
|
|
var sel = e.currentTarget;
|
|
var weg = sel.options[e.detail.index];
|
|
if (!weg) return;
|
|
var doel = sel.querySelectorAll('optgroup')[1];
|
|
var gekozen = sel.value;
|
|
doel.insertBefore(weg, doel.firstChild);
|
|
sel.value = gekozen;
|
|
});
|
|
|
|
var lev = document.getElementById('lev'), fab = document.getElementById('fab');
|
|
function herlaad(){
|
|
var inclusief = document.getElementById('incl').checked;
|
|
vul(lev, inclusief ? 850 : 120, 0);
|
|
vul(fab, inclusief ? 400 : 60, 500);
|
|
}
|
|
document.getElementById('incl').addEventListener('change', herlaad);
|
|
herlaad();
|
|
|
|
lev.addEventListener('change', function(){
|
|
console.log('[fixture] change op leverancier:', lev.value, '/', lev.options[lev.selectedIndex].textContent);
|
|
});
|
|
|
|
document.getElementById('f').addEventListener('submit', function(e){
|
|
e.preventDefault();
|
|
var d = new FormData(e.target);
|
|
document.getElementById('uit').textContent =
|
|
'verzonden:\n leverancier = ' + d.get('leverancier') +
|
|
'\n fabricaat = ' + d.get('fabricaat') +
|
|
'\n groep = ' + d.get('groep') +
|
|
'\n klein = ' + d.get('klein') +
|
|
'\n (label leverancier: ' + (lev.options[lev.selectedIndex] || {textContent:''}).textContent + ')';
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|