wip
This commit is contained in:
parent
286bd61497
commit
1386b80d0c
@ -7,113 +7,8 @@
|
|||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
import Select from "svelte-select";
|
import Select from "svelte-select";
|
||||||
import toast from "svelte-french-toast";
|
import toast from "svelte-french-toast";
|
||||||
import { onMount } from "svelte";
|
|
||||||
import VirtualSelect from "./VirtualSelect.svelte";
|
import VirtualSelect from "./VirtualSelect.svelte";
|
||||||
|
|
||||||
//
|
|
||||||
let options = [
|
|
||||||
{ label: "Bulbasaur", value: { id: 456 } },
|
|
||||||
{ label: "Ivysaur", value: { id: 456 } },
|
|
||||||
{ label: "Venusaur", value: { id: 456 } },
|
|
||||||
{ label: "Charmander", value: { id: 456 } },
|
|
||||||
{ label: "Charmeleon", value: { id: 456 } },
|
|
||||||
{ label: "Charizard", value: { id: 456 } },
|
|
||||||
{ label: "Squirtle", value: { id: 456 } },
|
|
||||||
{ label: "Wartortle", value: { id: 456 } },
|
|
||||||
{ label: "Blastoise", value: { id: 456 } },
|
|
||||||
{ label: "Caterpie", value: { id: 456 } },
|
|
||||||
{ label: "Metapod", value: { id: 456 } },
|
|
||||||
{ label: "Butterfree", value: { id: 456 } },
|
|
||||||
{ label: "Weedle", value: { id: 456 } },
|
|
||||||
{ label: "Kakuna", value: { id: 456 } },
|
|
||||||
{ label: "Beedrill", value: { id: 456 } },
|
|
||||||
{ label: "Pidgey", value: { id: 456 } },
|
|
||||||
{ label: "Pidgeotto", value: { id: 456 } },
|
|
||||||
{ label: "Pidgeot", value: { id: 456 } },
|
|
||||||
{ label: "Rattata", value: { id: 456 } },
|
|
||||||
{ label: "Raticate", value: { id: 456 } },
|
|
||||||
{ label: "Spearow", value: { id: 456 } },
|
|
||||||
{ label: "Fearow", value: { id: 456 } },
|
|
||||||
{ label: "Ekans", value: { id: 456 } },
|
|
||||||
{ label: "Arbok", value: { id: 456 } },
|
|
||||||
{ label: "Pikachu", value: { id: 456 } },
|
|
||||||
{ label: "Raichu", value: { id: 456 } },
|
|
||||||
{ label: "Sandshrew", value: { id: 456 } },
|
|
||||||
{ label: "Sandslash", value: { id: 456 } },
|
|
||||||
{ label: "Nidoran♀", value: { id: 456 } },
|
|
||||||
{ label: "Nidorina", value: { id: 456 } },
|
|
||||||
{ label: "Nidoqueen", value: { id: 456 } },
|
|
||||||
{ label: "Nidoran♂", value: { id: 456 } },
|
|
||||||
{ label: "Nidorino", value: { id: 456 } },
|
|
||||||
{ label: "Nidoking", value: { id: 456 } },
|
|
||||||
{ label: "Clefairy", value: { id: 456 } },
|
|
||||||
{ label: "Clefable", value: { id: 456 } },
|
|
||||||
{ label: "Vulpix", value: { id: 456 } },
|
|
||||||
{ label: "Ninetales", value: { id: 456 } },
|
|
||||||
{ label: "Jigglypuff", value: { id: 456 } },
|
|
||||||
{ label: "Wigglytuff", value: { id: 456 } },
|
|
||||||
{ label: "Zubat", value: { id: 456 } },
|
|
||||||
{ label: "Golbat", value: { id: 456 } },
|
|
||||||
{ label: "Oddish", value: { id: 456 } },
|
|
||||||
{ label: "Gloom", value: { id: 456 } },
|
|
||||||
{ label: "Vileplume", value: { id: 456 } },
|
|
||||||
{ label: "Paras", value: { id: 456 } },
|
|
||||||
{ label: "Parasect", value: { id: 456 } },
|
|
||||||
{ label: "Venonat", value: { id: 456 } },
|
|
||||||
{ label: "Venomoth", value: { id: 456 } },
|
|
||||||
{ label: "Diglett", value: { id: 456 } },
|
|
||||||
{ label: "Dugtrio", value: { id: 456 } },
|
|
||||||
{ label: "Meowth", value: { id: 456 } },
|
|
||||||
{ label: "Persian", value: { id: 456 } },
|
|
||||||
{ label: "Psyduck", value: { id: 456 } },
|
|
||||||
{ label: "Golduck", value: { id: 456 } },
|
|
||||||
{ label: "Mankey", value: { id: 456 } },
|
|
||||||
{ label: "Primeape", value: { id: 456 } },
|
|
||||||
{ label: "Growlithe", value: { id: 456 } },
|
|
||||||
{ label: "Arcanine", value: { id: 456 } },
|
|
||||||
{ label: "Poliwag", value: { id: 456 } },
|
|
||||||
{ label: "Poliwhirl", value: { id: 456 } },
|
|
||||||
{ label: "Poliwrath", value: { id: 456 } },
|
|
||||||
{ label: "Abra", value: { id: 456 } },
|
|
||||||
{ label: "Kadabra", value: { id: 456 } },
|
|
||||||
{ label: "Alakazam", value: { id: 456 } },
|
|
||||||
{ label: "Machop", value: { id: 456 } },
|
|
||||||
{ label: "Machoke", value: { id: 456 } },
|
|
||||||
{ label: "Machamp", value: { id: 456 } },
|
|
||||||
{ label: "Bellsprout", value: { id: 456 } },
|
|
||||||
{ label: "Weepinbell", value: { id: 456 } },
|
|
||||||
{ label: "Victreebel", value: { id: 456 } },
|
|
||||||
{ label: "Tentacool", value: { id: 456 } },
|
|
||||||
{ label: "Tentacruel", value: { id: 456 } },
|
|
||||||
{ label: "Geodude", value: { id: 456 } },
|
|
||||||
{ label: "Graveler", value: { id: 456 } },
|
|
||||||
{ label: "Golem", value: { id: 456 } },
|
|
||||||
{ label: "Ponyta", value: { id: 456 } },
|
|
||||||
{ label: "Rapidash", value: { id: 456 } },
|
|
||||||
{ label: "Slowpoke", value: { id: 456 } },
|
|
||||||
{ label: "Slowbro", value: { id: 456 } },
|
|
||||||
{ label: "Magnemite", value: { id: 456 } },
|
|
||||||
{ label: "Magneton", value: { id: 456 } },
|
|
||||||
{ label: "Farfetch'd", value: { id: 456 } },
|
|
||||||
{ label: "Doduo", value: { id: 456 } },
|
|
||||||
{ label: "Dodrio", value: { id: 456 } },
|
|
||||||
{ label: "Seel", value: { id: 456 } },
|
|
||||||
{ label: "Dewgong", value: { id: 456 } },
|
|
||||||
{ label: "Grimer", value: { id: 456 } },
|
|
||||||
{ label: "Muk", value: { id: 456 } },
|
|
||||||
{ label: "Shellder", value: { id: 456 } },
|
|
||||||
{ label: "Cloyster", value: { id: 456 } },
|
|
||||||
{ label: "Gastly", value: { id: 456 } },
|
|
||||||
{ label: "Haunter", value: { id: 456 } },
|
|
||||||
];
|
|
||||||
let selectedOption;
|
|
||||||
|
|
||||||
function handleSelect(event) {
|
|
||||||
selectedOption = event.detail;
|
|
||||||
console.log("Selected:", selectedOption);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
|
|
||||||
let runners = [];
|
let runners = [];
|
||||||
let donors = [];
|
let donors = [];
|
||||||
let runnerinfo = { id: 0, firstname: "", lastname: "" };
|
let runnerinfo = { id: 0, firstname: "", lastname: "" };
|
||||||
@ -157,15 +52,16 @@
|
|||||||
}
|
}
|
||||||
loadDonors();
|
loadDonors();
|
||||||
|
|
||||||
const getRunnerLabel = (option) =>
|
const getRunnerLabel = (option) => {
|
||||||
option.firstname +
|
return (
|
||||||
" " +
|
[option.firstname, option.middlename, option.lastname]
|
||||||
(option.middlename || "") +
|
.join(" ")
|
||||||
" " +
|
.replace(" ", " ") +
|
||||||
option.lastname +
|
|
||||||
" [#" +
|
" [#" +
|
||||||
option.id +
|
option.id +
|
||||||
"]";
|
"]"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const filterRunners = (label, filterText, option) => {
|
const filterRunners = (label, filterText, option) => {
|
||||||
if (filterText.startsWith("#")) {
|
if (filterText.startsWith("#")) {
|
||||||
@ -188,10 +84,6 @@
|
|||||||
c.click();
|
c.click();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
document.querySelector("#wrapper_runner_select input").focus();
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
@ -211,40 +103,27 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
<h4 class="text-xl font-semibold">{$_("runner")}</h4>
|
||||||
<VirtualSelect
|
<VirtualSelect
|
||||||
{options}
|
autofocus={true}
|
||||||
filterFn={(option, searchTerm) => {
|
on:onClear={() => {
|
||||||
// Example: Match if option starts with search term (case-insensitive)
|
console.log("Cleared selection");
|
||||||
return option.label.toLowerCase().startsWith(searchTerm.toLowerCase());
|
|
||||||
}}
|
}}
|
||||||
bind:selected={selectedOption}
|
options={runners}
|
||||||
|
filterFn={(option, searchTerm) => {
|
||||||
|
return option.label.toLowerCase().includes(searchTerm.toLowerCase());
|
||||||
|
}}
|
||||||
|
bind:selected={runnerinfo}
|
||||||
|
inputAriaLabel={$_("search-for-runner-by-name-or-id")}
|
||||||
inputPlaceholder={$_("search-for-runner-by-name-or-id")}
|
inputPlaceholder={$_("search-for-runner-by-name-or-id")}
|
||||||
noOptionsText={$_("no-runners-found")}
|
noOptionsText={$_("no-runners-found")}
|
||||||
on:select={handleSelect}
|
on:onSelected={() => {
|
||||||
/>
|
|
||||||
{#if selectedOption}
|
|
||||||
<p class="mt-4 text-lg">Selected: {JSON.stringify(selectedOption)}</p>
|
|
||||||
{/if}
|
|
||||||
<!-- -->
|
|
||||||
|
|
||||||
<!-- Runner Selection -->
|
|
||||||
<div id="wrapper_runner_select">
|
|
||||||
<h4 class="text-xl font-semibold">{$_("runner")}</h4>
|
|
||||||
<Select
|
|
||||||
containerClasses="rounded-md mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 border bg-gray-50 text-neutral-800 rounded-md p-2"
|
|
||||||
itemFilter={(label, filterText, option) =>
|
|
||||||
filterRunners(label, filterText, option)}
|
|
||||||
items={runners}
|
|
||||||
showChevron={true}
|
|
||||||
placeholder={$_("search-for-runner-by-name-or-id")}
|
|
||||||
noOptionsMessage={$_("no-runners-found")}
|
|
||||||
on:select={(selectedValue) => {
|
|
||||||
runnerinfo = selectedValue.detail.value;
|
|
||||||
document.querySelector("#donation_amount_eur").focus();
|
document.querySelector("#donation_amount_eur").focus();
|
||||||
}}
|
}}
|
||||||
on:clear={() => (runnerinfo = { id: 0, firstname: "", lastname: "" })}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
<!-- {#if runnerinfo}
|
||||||
|
<p class="mt-4 text-lg">Selected: {JSON.stringify(runnerinfo)}</p>
|
||||||
|
{/if} -->
|
||||||
|
|
||||||
<!-- Amount Input -->
|
<!-- Amount Input -->
|
||||||
<div>
|
<div>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
export let toggleAriaLabel = "Toggle dropdown";
|
export let toggleAriaLabel = "Toggle dropdown";
|
||||||
export let clearAriaLabel = "Clear selection";
|
export let clearAriaLabel = "Clear selection";
|
||||||
export let filterFn = null; // Custom filter function
|
export let filterFn = null; // Custom filter function
|
||||||
|
export let autofocus = false; // Autofocus input
|
||||||
|
|
||||||
// Internal state
|
// Internal state
|
||||||
let searchTerm = "";
|
let searchTerm = "";
|
||||||
@ -21,6 +22,7 @@
|
|||||||
let itemHeight = 40; // Fixed height for each option (in pixels)
|
let itemHeight = 40; // Fixed height for each option (in pixels)
|
||||||
let visibleCount = 10; // Default number of items to render
|
let visibleCount = 10; // Default number of items to render
|
||||||
let focusedIndex = -1; // Track the focused option index (-1 means no focus)
|
let focusedIndex = -1; // Track the focused option index (-1 means no focus)
|
||||||
|
let inputElement; // Reference to input element
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
@ -69,7 +71,7 @@
|
|||||||
function selectOption(option) {
|
function selectOption(option) {
|
||||||
selected = option.value;
|
selected = option.value;
|
||||||
isOpen = false;
|
isOpen = false;
|
||||||
searchTerm = "";
|
searchTerm = option.label;
|
||||||
focusedIndex = -1;
|
focusedIndex = -1;
|
||||||
dispatch("onSelected", option.value);
|
dispatch("onSelected", option.value);
|
||||||
}
|
}
|
||||||
@ -80,6 +82,7 @@
|
|||||||
searchTerm = "";
|
searchTerm = "";
|
||||||
focusedIndex = -1;
|
focusedIndex = -1;
|
||||||
dispatch("onSelected", null);
|
dispatch("onSelected", null);
|
||||||
|
dispatch("onClear");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle dropdown
|
// Toggle dropdown
|
||||||
@ -157,11 +160,14 @@
|
|||||||
updateVisibleItems();
|
updateVisibleItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize container size observer
|
// Initialize container size observer and autofocus
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (container) {
|
if (container) {
|
||||||
const resizeObserver = new ResizeObserver(updateVisibleCount);
|
const resizeObserver = new ResizeObserver(updateVisibleCount);
|
||||||
resizeObserver.observe(container);
|
resizeObserver.observe(container);
|
||||||
|
if (autofocus && inputElement) {
|
||||||
|
inputElement.focus();
|
||||||
|
}
|
||||||
return () => resizeObserver.disconnect();
|
return () => resizeObserver.disconnect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -186,6 +192,7 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={searchTerm}
|
bind:value={searchTerm}
|
||||||
|
bind:this={inputElement}
|
||||||
placeholder={getDisplayText()}
|
placeholder={getDisplayText()}
|
||||||
class="w-full bg-transparent focus:outline-none {selected
|
class="w-full bg-transparent focus:outline-none {selected
|
||||||
? 'text-black'
|
? 'text-black'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user