-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is it compatible with Svelte 3? #9
Comments
It's not. The syntax is very different. Is anyone working on updating this for the latest SvelteJS? |
Not updated for svelte v3 yet. As soon as I have the time... |
Happy to help if you could explain to me the logic behind it. I'm learning Svelte right now and this would be a great exercise for me, though I'm very beginner atm. I'm trying to understand how it works in plain javascript here - https://www.w3schools.com/howto/howto_js_autocomplete.asp but it looks more complicated than it needs to be! |
Svelte 3.6.7 @mikeyhan1 @odoo-mastercore
https://svelte.dev/repl/72a022c606aa4509abc6b00401538235?version=3.6.7 Gets you 99% of the way there |
Thanks for this, @northkode ! Looks good, but why do you say 'gets you 99% there'? |
Some of the padding and styles aren't perfect. Didnt want to say it was perfect cause I only spent about 10 minutes on it! Lol |
Perfect, Gonna steal this and tweak a little for my project. Thanks Guys |
Wondering about the onupdate function is that just a remnant of pre-v3 svelte? seems similar to the current store.update, but I'm not grokking it. |
Sorry @jdevine , it's not compatible with Svelte v3 yet. Haven't had the time yet to update. |
@northkode : Impressive :) Did you get async to work as well? |
I did on a local copy. Not on this one above however. I could try find it and post an update. |
I took what @northkode did and tweaked it a bit for my local implementation. I removed a lot of the flexibility, again, for brevity and the fact I'm only using it for a specific project. Could put a PR in that's more aligned with the original if people are interested. @tomzij this is how I handled the async piece, not sure if it's usable for everyone's scenario. <script>
import { scale } from "svelte/transition";
import { quintOut } from "svelte/easing";
const regExpEscape = s => {
return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
};
export let asyncFunc = null;
export let id = "";
export let items = [];
export let maxItems = 10;
export let minChar = 2;
export let name = "";
export let results = [];
export let value = {};
let arrowCounter = 0;
let input;
let loading = false;
let open = false;
let search = "";
let timer = null;
const clickAway = event => {
timer = setTimeout(() => {
open = false;
}, 200);
};
const clickOn = event => clearTimeout(timer);
const onChange = event => {
const term = event.target.value;
if (term.length >= Number(minChar)) {
if (asyncFunc !== null) {
loading = true;
clearTimeout(timer);
timer = setTimeout(async () => {
items = await asyncFunc(term);
loading = false;
open = true;
filterResults(term);
}, 500);
} else {
open = true;
filterResults(term);
}
} else {
results = [];
}
};
const filterResults = term => {
results = items
.filter(item => {
if (typeof item !== "string") item = item.value || "";
return item.toUpperCase().includes(term.toUpperCase());
})
.map((item, i) => {
const text = typeof item !== "string" ? item.value : item;
return {
key: item.key || i,
value: text,
label:
term.trim() === ""
? text
: text.replace(
RegExp(regExpEscape(term.trim()), "i"),
"<span class='font-semibold'>$&</span>"
)
};
})
.slice(0, maxItems - 1);
};
const onKeyDown = event => {
if (event.keyCode === 40 && arrowCounter < results.length - 1) {
arrowCounter++;
} else if (event.keyCode === 38 && arrowCounter > 0) {
arrowCounter--;
} else if (event.keyCode === 13) {
event.preventDefault();
if (arrowCounter === -1) arrowCounter = 0;
close(arrowCounter);
} else if (event.keyCode === 27) {
event.preventDefault();
close();
}
};
const close = (index = -1) => {
open = false;
arrowCounter = -1;
input.blur();
if (index > -1) {
value = results[index];
search = results[index].value;
} else {
search = "";
}
};
</script>
<div class="mt-1 relative rounded-md shadow-sm">
<input
on:blur={clickAway}
on:focus={clickOn}
on:keydown={event => onKeyDown(event)}
on:input={event => onChange(event)}
bind:value={search}
bind:this={input}
class="form-input block w-full pr-10 sm:text-sm sm:leading-5"
type="text"
{id}
{name} />
{#if loading}
<div
class="absolute inset-y-0 right-0 pr-3 flex items-center
pointer-events-none">
<img class="h-4 w-4 opacity-50" src="/bars_dark.svg" alt="Loading" />
</div>
{/if}
{#if open}
<div
class="origin-top-right absolute right-0 mt-2 w-full rounded-md shadow-lg
z-10"
transition:scale={{ duration: 150, delay: 0, opacity: 0.2, start: 0.0, easing: quintOut }}>
<div class="rounded-md bg-white shadow-xs">
<div class="py-1">
{#if results.length === 0}
<div
class="block px-4 py-2 text-sm cursor-pointer text-gray-700
hover:bg-gray-100">
No matches
</div>
{:else}
{#each results as result, i}
<div
on:click={() => close(i)}
class="block px-4 py-2 text-sm cursor-pointer text-gray-700
hover:bg-gray-100 {i === arrowCounter ? 'bg-gray-100' : ''}">
{@html result.label}
</div>
{/each}
{/if}
</div>
</div>
</div>
{/if}
</div> |
@northkode Could you post an update with async? That would be great! |
@svmartin This is a simple example. https://svelte.dev/repl/7641903573c943799c63f9772b0d033f?version=3.24.0 |
No description provided.
The text was updated successfully, but these errors were encountered: