completed autocomplete box in permission editor for projects

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2026-03-17 00:35:49 +01:00
parent ef71cf3b20
commit d3e5897cd5
3 changed files with 58 additions and 43 deletions

View File

@@ -9,11 +9,11 @@
onSelect = dummyOnSelect,
} = $props();
const ignore = ['Escape','Tab','ArrowUp','ArrowLeft','ArrowRight'];
const ignore = ['ArrowLeft','ArrowRight'];
let candidate = $state({ display : '' });
let selected = $state([]);
let candidates = $derived(getCandidates(candidate.display));
async function dummyGetCandidates(text){
console.warn(`getCandidates(${text}) not overridden!`);
if (!text) return [];
@@ -35,7 +35,7 @@
// if Enter is pressed on the input field, this method gets called with
// either the selected candidate or
// an anonymous object with the entered text in the display field
console.warn('onCommit not overridden!');
console.warn(`onCommit(${JSON.stringify(candidate)}) not overridden!`);
}
function dummyOnSelect(candidate){
@@ -43,31 +43,63 @@
}
async function onkeyup(ev){
const select = ev.target;
const key = ev.key;
if (ignore.includes(key)) return;
if (ignore.includes(ev.key)) return;
if (ev.key == 'ArrowDown'){
ev.preventDefault();
selected = selected.length < 1 ? [0] : [selected[0]+1]
if (selected[0] >= candidates.length) selected = [0];
return false;
}
if (ev.key == 'ArrowUp'){
ev.preventDefault();
selected = selected.length < 1 ? [-1] : [selected[0]-1]
if (selected[0] < 0) selected = [candidates.length-1];
return false;
}
if (ev.key == 'Enter'|| ev.key == 'Tab'){
ev.preventDefault();
if (selected.length>0) {
candidate = candidates[selected[0]];
candidates = [];
selected = [];
onSelect(candidate);
return false;
}
if (ev.key == 'Enter') {
candidates = [];
selected = [];
onCommit(candidate);
}
return false;
}
if (ev.key == 'Escape'){
ev.preventDefault();
candidates = [];
selected = [];
return false;
}
candidates = await getCandidates(candidate.display);
if (selected>candidates.length) selected = candidates.length;
return false;
}
</script>
<style>
div { position : relative }
select { position : absolute; top: 30px; left: 3px; }
select { background: black; color: orange; border: 1px solid orange; border-radius: 5px; }
option:checked { background: orange; color: black; }
</style>
<div>
<input type="text" bind:value={candidate.display} {onkeyup} />
{#if candidates && candidates.length > 1}
<select multiple>
{#each candidates as candidate (candidate.display)}
<option value={candidate}>{candidate.display}</option>
{#if candidates && candidates.length > 0}
<select bind:value={selected} multiple tabindex="-1">
{#each candidates as candidate,i}
<option value={i}>{candidate.display}</option>
{/each}
</select>
{/if}
</div>
{#if candidates}
<pre>
{JSON.stringify(candidates,null,2)}
</pre>
{/if}
{JSON.stringify(candidate)}
</div>