Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

salioudiabate's avatar

Issues with Updating Multiple Select Components Dynamically with Alpine.js and Livewire

Hello everyone,

I'm facing an issue with dynamically updating multiple select components on a page. I'm using a combination of Alpine.js and Livewire for this.

The component works well when used individually, but when I have multiple instances of the same component, the updates don't propagate correctly to the other selects when I change one of them.

Here's the relevant part of my code:

https://imgur.com/a/Rf3b0mF (Illustration link)

    <!-- trigger button  -->
    <button type="button" role="list"
            class="{{ $attributes->get('button-class', '') }}"
            aria-haspopup="listbox" aria-controls="itemsList"
            x-on:click="isOpen = ! isOpen" x-on:keydown.down.prevent="openedWithKeyboard = true"
            x-on:keydown.enter.prevent="openedWithKeyboard = true" x-on:keydown.space.prevent="openedWithKeyboard = true"
            x-bind:aria-expanded="isOpen || openedWithKeyboard"
            x-bind:aria-label="selectedOption ? selectedOption[optionLabel] : selectDefaultMessage">
        <span class="{{ $attributes->get('button-text-class', 'w-full text-left text-gray-700 text-base truncate') }}" x-text="selectedOption ? selectedOption[optionLabel] : selectDefaultMessage"></span>
        <!-- Chevron  -->
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="size-5">
            <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd"/>
        </svg>
    </button>

    <input id="{{ $attributes->get('id', 'dropdown') }}" name="{{ $attributes->get('name', 'dropdown') }}" x-ref="hiddenTextField" hidden="" />

    <ul x-cloak x-show="isOpen || openedWithKeyboard" id="itemsList" class="absolute py-1.5 z-10 left-0 top-11 flex max-h-44 w-full flex-col overflow-hidden overflow-y-auto rounded-md border border-neutral-300 {{ $attributes->get('item-list-bg') }}"
        role="listbox" aria-label="items list"
        x-on:click.outside="isOpen = false, openedWithKeyboard = false"
        x-on:keydown.down.prevent="$focus.wrap().next()"
        x-on:keydown.up.prevent="$focus.wrap().previous()"
        x-transition x-trap="openedWithKeyboard">
        <template x-for="(item, index) in options" x-bind:key="item[optionValue]">
            <li class="select-option {{ $attributes->get('item-list-class') }}" role="option"
                x-on:click="setSelectedOption(item)"
                x-on:keydown.enter="setSelectedOption(item)" x-bind:id="'option-' + index" tabindex="0" >
                <!-- Label  -->
                <span x-bind:class="selectedOption == item ? 'font-bold' : null" x-text="item[optionLabel]"></span>
                <!-- Screen reader 'selected' indicator  -->
                <span class="sr-only" x-text="selectedOption == item ? 'selected' : null"></span>
                <!-- Checkmark  -->
                <svg x-cloak x-show="selectedOption == item" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" class="size-4" aria-hidden="true">
                    <path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/>
                </svg>
            </li>
        </template>
    </ul>
</div>

public function updatedFormCompanyId($value): void
{
    $this->stations = Station::query()
        ->where('company_id', '=', $value)
        ->get();
    $this->form->station_start = '';
    $this->form->station_end = '';
}
0 likes
1 reply

Please or to participate in this conversation.