Alpine applying class

What seems to be the problem:
Using Alpine inside Livewire component, i’m able to add an active class, but it does not remove the active class once i click on another button,

@foreach ($locations as $key => $location) {{ $location['name'] }} @endforeach

The method on the wire:click call is this:
public function selectedCity($cityName): void
{
$this->selected = $this->getCityName($cityName);

$this->emit('locationChanged');

}

it emit a broadcast so another component responsible for changing the location to the current clicked button.

In the screenshot you can see the active state still active on both clicked button.

is there a workaround this please ?

Are you using the latest version of Livewire: yes

Do you have any screenshots or code examples: yes

Are you trying to add/remove the class via livewire or alpine? I’d recommend just handling the CSS stuff with Alpine. If you can paste a code sample for how you’re managing the active class, that would be helpful. Trying to manage front-end states in livewire through eventing will likely cause pretty significant lag in UI in production due to the roundtrip time.

Hi @shortbrownman
Thanks for your reply, the code i’ve provided got cut for no reason, so here is the sample responsible for adding / removing class.

as i said, i’m using Alpine to add a class ‘bg-white’, but once i click on another button the previous button doesn’t loose ‘bg-white’ and i don’t know why

div class=“flex xl-max:flex-col” id=“locations” >
@foreach ($locations as $key => $location)
<button x-data="{ clicked: false }"
type=“button”
x-bind:class="{ ‘bg-white’: clicked, ‘bg-chalk34 border-cave’: !clicked }"
@click=“clicked = ! clicked”
wire:key="{{ $key }}"
wire:click=“selectedCity(’{{ $location[‘name’] }}’)”
class=“form-locationSelect__button border-1 hover:bg-white copy” >
{{ $location[‘name’] }}

@endforeach

The clicked variable is scoped to your single button component. Nothing can change that specific click outside of actions taken place within that button’s scope. If you were to toggle click within the button, it’ll work. But other actions cannot access that. You’ll have to move the x-data scope up and have separate click variables for each of your buttons if you want to handle it this way then onClick from another button, you’ll need to toggle that every other click instance to false. It’s a pretty convoluted way of handling things. Alternately, you can keep track of the ‘active’ element in your x-data and apply styling based on that. It’s a little simpler of an approach.

Try something like this:

<div x-data="{ activeButton: ''}">
    @foreach ($locations as $key => $location)
        <button type=“button” :class="{ 'bg-white': activeButton === '{{ $key }}', 'bg-chalk34 border-cave': activeButton != '{{ $key }}' }" :click="activeButton = '{{ $key }}'" wire:key="{{ $key }}" wire:click=“selectedCity(’{{[‘name’] }}’)” class=“form-locationSelect__button border-1 hover:bg-white copy”>$location[‘name’] }}</button>
    @endforeach
</div>

What it’s doing is using the $key in your loop to set a unique identifier for each button. Once a button is clicked, it sets activeButton within x-data to that button’s $key. From there, it will apply the styles accordingly. If activeButton === $key then it will get the bg-white class. Otherwise, it’ll get the bg-chalk34 border-cave classes applied.

i’ve tried your code like so but unfortunatly did not trigger to active state at all.

@foreach ($locations as $key => $location)
    <button type='button'
            :class="{ 'bg-white': activeButton === {{ $key }}, 'bg-chalk34 border-cave': activeButton !== {{ $key }} }"
            :click="activeButton = {{ $key }}"
            wire:key="{{ $key }}"
            class="form-locationSelect__button border-1 hover:bg-white copy">
       {{ $location['name'] }}
    </button>

@endforeach

i deactivated the Livewire method to test without firing the event. no luck.

There’s an extra = in your code after activeButton != which could be affecting things.