Make better autocomplete selections
This commit is contained in:
@@ -23,9 +23,8 @@
|
||||
let nameElement: HTMLTableCellElement;
|
||||
let autocompleteList: HTMLUListElement;
|
||||
let foodSearch: main.Food[] = [];
|
||||
let hiLiteIndex: number = -1;
|
||||
|
||||
// Maybe it would be a good idea to use $ instead of update down there...
|
||||
// Maybe it's a topic for another day
|
||||
$: {
|
||||
name = name.trim();
|
||||
if (!name) {
|
||||
@@ -38,16 +37,37 @@
|
||||
function updateAutocomplete() {
|
||||
if (!per100Edited)
|
||||
GetLastPer100(name.trim()).then((res) => {
|
||||
// Prevent search when there's nothing to search
|
||||
// Sometimes we get search results after deleting name
|
||||
if (res.success && res.data && name) {
|
||||
foodSearch = res.data;
|
||||
hiLiteIndex = -1;
|
||||
} else {
|
||||
foodSearch = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
item.food = name;
|
||||
item.description = description;
|
||||
item.amount = parseInt(amount);
|
||||
item.per100 = parseInt(per100);
|
||||
|
||||
const res = await CreateFood(item);
|
||||
name = "";
|
||||
amount = "";
|
||||
per100 = "";
|
||||
per100Edited = false;
|
||||
|
||||
if (!res.success) {
|
||||
toast.error(`failed to create item with error ${res.error}`);
|
||||
return;
|
||||
}
|
||||
|
||||
foodStore.update((value) => [res.data, ...value]);
|
||||
nameElement.focus();
|
||||
foodSearch = [];
|
||||
}
|
||||
|
||||
async function update(event: KeyboardEvent & { currentTarget: EventTarget & HTMLTableCellElement }) {
|
||||
name = name.trim();
|
||||
amount = amount.trim();
|
||||
@@ -61,53 +81,48 @@
|
||||
|
||||
if (!per100Edited && event.currentTarget == per100Element) per100Edited = true;
|
||||
|
||||
if (event.key == "Enter") {
|
||||
if (event.key === "Enter") {
|
||||
event.preventDefault();
|
||||
item.food = name;
|
||||
item.description = description;
|
||||
item.amount = parseInt(amount);
|
||||
item.per100 = parseInt(per100);
|
||||
|
||||
const res = await CreateFood(item);
|
||||
name = "";
|
||||
amount = "";
|
||||
// description = ''
|
||||
per100 = "";
|
||||
per100Edited = false;
|
||||
|
||||
if (!res.success) {
|
||||
toast.error(`failed to create item with error ${res.error}`);
|
||||
// If suggestions are visible and we have a highlighted item or at least one suggestion
|
||||
if (foodSearch.length > 0) {
|
||||
const selectedFood = hiLiteIndex >= 0 ? foodSearch[hiLiteIndex] : foodSearch[0];
|
||||
setInputVal(selectedFood);
|
||||
return;
|
||||
}
|
||||
|
||||
foodStore.update((value) => [res.data, ...value]);
|
||||
nameElement.focus();
|
||||
foodSearch = [];
|
||||
// Only submit if we have no suggestions visible
|
||||
if (name && amount && per100) {
|
||||
await handleSubmit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function navigateList(e: KeyboardEvent) {
|
||||
if (!foodSearch.length) return;
|
||||
|
||||
switch (e.key) {
|
||||
case "ArrowDown":
|
||||
e.preventDefault();
|
||||
hiLiteIndex = Math.min(hiLiteIndex + 1, foodSearch.length - 1);
|
||||
break;
|
||||
case "ArrowUp":
|
||||
e.preventDefault();
|
||||
hiLiteIndex = Math.max(hiLiteIndex - 1, -1);
|
||||
break;
|
||||
case "Escape":
|
||||
e.preventDefault();
|
||||
foodSearch = [];
|
||||
hiLiteIndex = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let hiLiteIndex: number | null = null;
|
||||
// function navigateList(e: KeyboardEvent) {
|
||||
// console.log(foodSearch, hiLiteIndex);
|
||||
// // @ts-ignore shut the fuck up
|
||||
// if (e.key == "ArrowDown" && hiLiteIndex <= foodSearch.length - 2) {
|
||||
// hiLiteIndex == null ? (hiLiteIndex = 0) : (hiLiteIndex += 1);
|
||||
// } else if (e.key == "ArrowUp" && hiLiteIndex !== null) {
|
||||
// hiLiteIndex == 0 ? 0 : (hiLiteIndex -= 1);
|
||||
// } else if (e.key == "Enter") {
|
||||
// // @ts-ignore ITS NOT NULL YOU ASSHAT
|
||||
// // WE CHECKED
|
||||
// // ITS NOT
|
||||
// setInputVal(foodSearch[hiLiteIndex]);
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
function setInputVal(food: main.Food) {
|
||||
name = food.food;
|
||||
per100 = String(food.per100);
|
||||
amount = String(food.amount);
|
||||
hiLiteIndex = null;
|
||||
hiLiteIndex = -1;
|
||||
foodSearch = [];
|
||||
}
|
||||
|
||||
@@ -123,6 +138,7 @@
|
||||
function handleFocusOut() {
|
||||
timeout = setTimeout(() => {
|
||||
foodSearch = [];
|
||||
hiLiteIndex = -1;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
@@ -132,7 +148,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- <svelte:window on:keydown={navigateList} /> -->
|
||||
<svelte:window on:keydown={navigateList} />
|
||||
|
||||
<template>
|
||||
<tr class="border-b border-gray-200 dark:border-gray-700 text-lg font-bold relative">
|
||||
@@ -180,7 +196,7 @@
|
||||
{#if foodSearch.length > 0}
|
||||
<ul bind:this={autocompleteList} class="z-50 fixed top-0 left-0 w-3/12 border border-x-gray-800">
|
||||
{#each foodSearch as f, i}
|
||||
<FoodSearchEntry itemLabel={f.food} highlighted={i == hiLiteIndex} on:click={() => setInputVal(f)} />
|
||||
<FoodSearchEntry itemLabel={f.food} highlighted={i === hiLiteIndex} on:click={() => setInputVal(f)} />
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
|
Reference in New Issue
Block a user