Search code examples
javascriptsvelte

Bind a div to a changing variable


There is a loop, which contains a button, on click that button a function runs,

{#each newArray as item (item.id)}
<button class="px-2 py-1" on:click={() => settingFun(item.id)}>(Id: {item.id})<Setting /></button>
{/each}


function settingFun(itemId) {
    toggle = !toggle;
    if (!toggle) {
      settings.classList.remove("hidden");
      settingIcon.classList.add("bg-gray-200", "rounded-lg");
    } else {
      settings.classList.add("hidden");
      settingIcon.classList.remove("bg-gray-200", "rounded-lg");
    }
  }


<div class="hidden" bind:this={settings}>
            <div class="flex justify-between items-center border py-2 shadow-md">
              <div class="flex py-3 px-2">
                <div class="bg-[#D9D9D9] px-3 py-2 rounded-lg font-semibold">
                  <Button label="Not Empty" />
                </div>
                <div class="ml-5 bg-[#D9D9D9] px-3 py-2 rounded-lg font-semibold">
                  <Button label="Is Unique" />
                </div>
              </div>
              <div class="flex relative menus">
            </div>
          </div>

i want to bind this div to item.id or something like connected with item.id [item.id is a unique id generated each time on when loop runs] and also use item.id in settingFun() instead of settings. In Conclusion, i want a different behaviour for each item in loop.

i tried to bind item.id in place of setting but didn't work and caused tab crash


Solution

  • You can make some changes in changes in JavaScript by finding the item based on itemId passed as an argument. After that you can toggle visibility of that div. I hope that helps.

    function settingFun(itemId) {
      const item = newArray.find(item => item.id === itemId);
      item.toggle = !item.toggle;
      if (!item.toggle) {
        item.settings.classList.remove("hidden");
        settingIcon.classList.add("bg-gray-200", "rounded-lg");
      } else {
        item.settings.classList.add("hidden");
        settingIcon.classList.remove("bg-gray-200", "rounded-lg");
      }
    }
    

    and html will be amended as

    {#each newArray as item (item.id)}
      {#if !item.hidden}
        <button class="px-2 py-1" on:click={() => settingFun(item.id)}>(Id: {item.id})<Setting /></button>
        <div class="hidden" bind:this={item.settings}>
          <div class="flex justify-between items-center border py-2 shadow-md">
            <div class="flex py-3 px-2">
              <div class="bg-[#D9D9D9] px-3 py-2 rounded-lg font-semibold">
                <Button label="Not Empty" />
              </div>
              <div class="ml-5 bg-[#D9D9D9] px-3 py-2 rounded-lg font-semibold">
                <Button label="Is Unique" />
              </div>
            </div>
            <div class="flex relative menus">
              <!-- Add your menu items here -->
            </div>
          </div>
        </div>
      {/if}
    {/each}