I am trying to create a sidebar menu with Alpine JS
I am not even sure if this is possible to do with Alpine JS.
@foreach($kanbans as $kanban) <div x-data="activeKanban : ????"> <div @click="activeKanban = {{$kanban->id}}"> <div x-show="activeKanban !== {{$kanban->id}}"> // Design for collapsed kanban </div> <div> <div x-show="activeKanban === {{$kanban->id}}"> // Design for active kanban </div> </div> @endforeach
As I switch trough the pages, the $kanban->id
changes, and I was wondering instead of manually setting activeKanban : 1
is there a way to pass this information to AlpineJS?
So that by default if I load the other page, the default menu that would be open would be based on the ID instead of them all being collapsed or just 1 that is specified being open?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
If you’re aiming for an accordion menu of sorts here’s how you might achieve it with AlpineJs based on the code you shared:
// Set x-data on a div outside the loop and add your active kanban as a property <div x-data="{ activeKanban: {{ $activeKanbanId ?? null }} }"> @foreach($kanbans as $kanban) <div @click="activeKanban = {{ $kanban->id }}"> <div x-show="activeKanban !== {{ $kanban->id }}"> // Collapsed view </div> <div x-show="activeKanban === {{ $kanban->id }}"> // Expanded view </div> </div> @endforeach </div>
Here each kanban menu item will have access to the activeKanban
property in AlpineJs component instance and can set it reactively.
i.e. if activeKanban
is set to a new id the current open item will close and the new one will open
Adding flexibility
What if you want to open and close them all independently though? There’s more than one way to achieve this but in this case we can modify the code above to allow for it:
// Here we add an array of openItems and two helper functions: // isOpen() - to check if the id is either the activeKanban or in the openItems array // toggle() - to add/remove the item from the openItems array <div x-data="{ activeKanban: {{ $activeKanbanId ?? null }}, openItems: [], isOpen(id){ return this.activeKanban == id || openItems.includes(id) }, toggle(id){ if(this.openItems.includes(id)){ this.openItems = this.openItems.filter(item => { return item !== id }); }else{ this.openItems.push(id) } } }"> @foreach($kanbans as $kanban) <div @click="toggle({{ $kanban->id }})"> <div x-show="!isOpen({{$kanban->id}})"> // Collapsed view </div> <div x-show="isOpen({{$kanban->id}})"> // Expanded view </div> </div> @endforeach </div>
This allows us to set an active item and also optionally open/close other menu items.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0