Skip to content Skip to sidebar Skip to footer

How To Marry This Todo List With Instant Search In Svelte?

EDIT for the tldr version scroll down to where it says I'm extremely close in the code below. Problem I have a basic todo list that when completed will have these qualities: When

Solution 1:

I got it. I set a copy of the clients array to a reactive array. Hopefully this helps someone out.

https://svelte.dev/repl/ad1c185bf97a47b98506c3603f510de6?version=3.30.0

<script>
    import { onMount } from 'svelte';
    let clients = ["a Little piggy","b little piggy","c little piggy"]; 
    $: clientsCopy = clients ;
    let indexVal = -1;
    let downArrowPress = 40;
    let upArrowPress = 38;
    let clientInputTextField = "";
    let clientVal = "";
    onMount(function() {
        clientInputTextField.focus();
    });


    function search(e){
    console.log(e.target.value)
    const searchString = e.target.value.toLowerCase();
    const filteredCharacters = clients.filter((character) => {
        return (
            character.toLowerCase().includes(searchString) ||
            character.toLowerCase().includes(searchString)
        );
    });
    
     clientsCopy = [...filteredCharacters]
    
    }


    function handleKeydown(event) {
        if(event.keyCode === upArrowPress) {
            indexVal-=1;    
            indexVal = indexVal < 0 ?  clientsCopy.length : indexVal
            console.log(indexVal);
        }

        if(event.keyCode === downArrowPress) {
            indexVal+=1;
            indexVal = indexVal > clientsCopy.length ?  0 : indexVal
            console.log(indexVal);
        }

        if(indexVal > clientsCopy.length -1 || indexVal < 0){
            clientInputTextField.focus(); 
        } else {
            clientInputTextField.blur()
        }   
    }
    
    function handleSubmit(e) {
        const value = e.target.input.value;
        console.log(value);
        clients = [...clients, value];
        clientVal = "";
    }
</script>



<svelte:window on:keydown={handleKeydown}/>

<form on:submit|preventDefault={handleSubmit}>
    <input type="text" name="input" bind:this={clientInputTextField}  bind:value={clientVal} on:input={search} autocomplete="off">
    <input type="submit" name="">
</form>

<ul>
    {#each clientsCopy as client, i}
        {#if i === indexVal}
            <li style="background-color:orange">{client}</li>
            {:else}
            <li style="">{client}</li>
        {/if}
    {/each}
</ul>




<!-- 


 -->

Solution 2:

This is a little more succint version of what you have, based on code found in a gist here. It's effectively the same as your solution though (i.e. creating and displaying a separate "filtered" list)!

<script>
    import { onMount } from 'svelte';
    let clients = ["a Little piggy","b little piggy","c little piggy"]; 
    let indexVal = -1;
    let downArrowPress = 40;
    let upArrowPress = 38;
    let clientInputTextField = "";
    let clientVal = "";
    
        const startsWith = (item, query) => item.toLowerCase().indexOf(query.toLowerCase()) != -1;
        $: filteredClients = clientVal && clientVal.length ? clients.filter(item => startsWith(item, clientVal)) : clients;
    
        onMount(function() {
            clientInputTextField.focus();
        });


    function handleKeydown(event) {
    if(event.keyCode === upArrowPress) {
            indexVal-=1;    
            indexVal = indexVal < 0 ?  clients.length : indexVal
            console.log(indexVal);
    }

    if(event.keyCode === downArrowPress) {
            indexVal+=1;
            indexVal = indexVal > clients.length ?  0 : indexVal
            console.log(indexVal);
    }

    if(indexVal > clients.length -1 || indexVal < 0){
            clientInputTextField.focus(); 
    } else {
        clientInputTextField.blur()
    }   
  }
    
    function onChange(e) {
        console.log("what")
        const searchTerm = e.target.value.toLowerCase();
        console.log(searchTerm)
        clients = clients.filter(client => client.toLowerCase().includes(searchTerm))
    }
    
    function handleSubmit(e) {
        const value = e.target.input.value;
        console.log(value);
        clients = [...clients, value];
        clientVal = "";
    }
</script>



<svelte:window on:keydown={handleKeydown}/>

<form on:submit|preventDefault={handleSubmit}>
<!--     <input type="text" name="input" on:change={onChange} bind:this={clientInputTextField}  bind:value={clientVal} autocomplete="off"> -->
    <input type="text" name="input" bind:this={clientInputTextField}  bind:value={clientVal} autocomplete="off">
    <input type="submit" name="">
</form>

<ul>
    {#each filteredClients as client, i}
        {#if i === indexVal}
            <li style="background-color:orange">{client}</li>
            {:else}
            <li style="">{client}</li>
        {/if}
    {/each}
</ul>

Post a Comment for "How To Marry This Todo List With Instant Search In Svelte?"