Search code examples
laravel-livewirealpine.js

How with alpine to make accordion with only 1 item opened?


In laravel 7 with livewire 1.3 and alpine@v2.x.x I made an accordion like:

<div class="accordion_wrapper">

    @foreach($faqs as $nextFaq)
        <div class="accordion_{{ $nextFaq->id }}" x-data="{ is_opened: false }">
            <button @click="is_opened= !is_opened">
                <div>Question {{ $nextFaq->id }}</div>
            </button>
            <div class="accordion_content" x-show="is_opened">
                {{ $nextFaq->id }} Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.
            </div>
        </div>
    @endforeach

</div>

and it works, but how can I make with alpine to have opened only 1 item? If user clicks on some other items, the rest of items must be closed.


Solution

  • Try saving the open tab index to x-data, instead of opened/closed boolean value, this way you can group the accordion items:

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.9.6/tailwind.min.css" integrity="sha512-l7qZAq1JcXdHei6h2z8h8sMe3NbMrmowhOl+QkP3UhifPpCW2MC4M0i26Y8wYpbz1xD9t61MLT9L1N773dzlOA==" crossorigin="anonymous" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/2.3.0/alpine.js"></script>
    
    <div class="p-4">
      <div x-data="{ opened_tab: null }" class="flex flex-col">
        <div class="flex flex-col border rounded shadow mb-2">
          <div @click="opened_tab = opened_tab == 0 ? null : 0 " class="p-4 cursor-pointer">Accordion Label #1</div>
          <div x-show="opened_tab==0" class="px-4 pb-4">
            Accordion Contents #1
          </div>
        </div>
        <div class="flex flex-col border rounded shadow mb-2">
          <div @click="opened_tab = opened_tab == 1 ? null : 1 " class="p-4 cursor-pointer">Accordion Label #2</div>
          <div x-show="opened_tab==1" class="px-4 pb-4">
            Accordion Contents #2
          </div>
        </div>
        <div class="flex flex-col border rounded shadow mb-2">
          <div @click="opened_tab = opened_tab == 2 ? null : 2 " class="p-4 cursor-pointer">Accordion Label #3</div>
          <div x-show="opened_tab==2" class="px-4 pb-4">
            Accordion Contents #3
          </div>
        </div>
      </div>
    </div>