Search code examples
javascriptsveltesveltekitsvelte-3daisyui

Modal component created in Svelte opening just once


I've got a modal component that looks like this:

<script>
    export let open = false;
    export let data = {};
    export let modalID = undefined;

    const closeModal = () => {
        console.log("closing modal...")
        open = false;

        // reset all fields
        data = {};
    }

    $: console.log(open)


</script>

{#if open}
<div class="modal" id="product-modal-{modalID}" class:modal-open={open}>
    <div class="modal-box relative w-56">
        <label for="product-modal-{modalID}" class="btn btn-sm btn-circle absolute right-2 top-2" on:click={closeModal}>✕</label>
        <div class="bg-white">
            <div class="flex items-center justify-center">
                <img class="object-scale-down h-40 w-40"
                     src="https://media.ldlc.com/r1600/ld/products/00/05/82/02/LD0005820208_1.jpg" alt=""
                />
            </div>
            <div class="py-2 px-2 bg-white">
                <p class="text-md font-semibold block text-gray-600">
                    { data.name }
                </p>
                <div class="flex flex-row py-4">
                    <div class="pr-8 pt-2 flex justify-between">
                        <span class="font-semibold">-</span>
                        <input type="text" class="focus:outline-none bg-gray-100 border h-6 w-8 rounded text-sm px-2 mx-2" value="1">
                        <span class="font-semibold">+</span>
                    </div>
                    <button class="btn btn-primary btn-sm">Add</button>
                </div>
            </div>
        </div>


    </div>
</div>
    {/if}

It's a fairly simple modal used at the moment to display some data. The modal is invoked from a page in which I'm dynamically displaying multiple products. When a product is clicked then the modal should appear and display the data for that specific product. It works fine for the first product I click on, but after closing the modal, if I click on any other product the modal does not appear again:


<script>
    import { productSearch } from "../../lib/api/products.js";
    import ProductModal from "../../lib/components/ProductModal.svelte";

    let openModal = false;
    let productData = {}

    const openProductModal = (data) => {
        console.log(data);
        productData = data;
        openModal = !openModal;
        console.log(openModal)
    }


</script>
{#if searchResults}

   {#each searchResults as result (result.searchable.id)}

       <div class="w-64 rounded-md overflow-hidden shadow-lg hover:scale-105 transition duration-500 bg-white">
           <div class="flex items-center justify-center">
               <img class="object-scale-down h-40 w-40"                                          
 src="https://media.ldlc.com/r1600/ld/products/00/05/82/02/LD0005820208_1.jpg" alt=""
                                        />
           </div>
       <div class="py-4 px-4 bg-white">
       <p class="text-md font-semibold block text-gray-600 line-clamp-3 h-20 max-h-20">
           { result.searchable.name }
       </p>
       <div class="flex flex-row justify-between">
   <p class="text-lg font-semibold text-black cursor-auto my-3">${ result.searchable.retail_price }</p>
   <a href="#" on:click={openProductModal(result.searchable)} class="btn btn-circle btn-outline">
   <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
   <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 10.5V6a3.75 3.75 0 10-7.5 0v4.5m11.356-1.993l1.263 12c.07.665-.45 1.243-1.119 1.243H4.25a1.125 1.125 0 01-1.12-1.243l1.264-12A1.125 1.125 0 015.513 7.5h12.974c.576 0 1.059.435 1.119 1.007zM8.625 10.5a.375.375 0 11-.75 0 .375.375 0 01.75 0zm7.5 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
   </svg>
</a>
        </div>
    </div>
</div>

{/each}
{/if}


{#if openModal}
<ProductModal open={openModal} data={productData} modalID={productData.id} />
{/if}

any idea what am i missing?


Solution

  • bind: is needed if changes to a passed prop should have an effect inside the parent component

    <ProductModal bind:open={openModal} ... />