Jochem Gruter
Jochem Gruter

Reputation: 2899

Get value of a toggle element

I am building a blade toggle component using AlpineJS. The idea is that you can enable/disable the UI toggle and a invissible checkbox will be put on/on

toggle.blade.php:

<div x-data="{on: false}">
    <button type="button" @click="on = !on" :class="{'bg-cyan-600' : on, 'bg-gray-200' : !on}">
        <span :class="{'translate-x-5' : on, 'translate-x-0' : !on}" class="..."></span>
    </button>

    <input type="checkbox" name="{{$name}}" x-model="on" value="on" class="hidden" />
</div>

This is working good so far. I can put the toggle in my form and toggle it:

<x-toggle name="test" />

But now I want other elements interact with this toggle. For example make another input field vissible by toggling the test-toggle on.

So it need to work something like this:

<div x-data="{show: false}">
    <x-toggle name="test" x-model="show" />
    
    <div x-show="show">
        <!-- input elements -->
    </div>
</div>

How can I achive this?

Upvotes: 0

Views: 722

Answers (1)

Irfan
Irfan

Reputation: 1030

This is a scenario with two alpine components, We need an inter-component communication to achieve the functionality.

Since alpine.js does not support accessing parent's or child's components, we can make use of events to handle this.

We can watch the on property in the toggle.blade.php and emit an event with the updated value.

toggle.blade.php:

<div x-data="{on: false}" x-init="$watch('on', val => $dispatch('toggle',val))">
    <button type="button" @click="on = !on" :class="{'bg-cyan-600' : on, 'bg-gray-200' : !on}">
        <span :class="{'translate-x-5' : on, 'translate-x-0' : !on}" class="..."></span>
    </button>

    <input type="checkbox" name="{{$name}}" x-model="on" value="on" class="hidden" />
</div>

Now in the parent, we can listen for the event toggle and set the show property accordingly.

<div x-data="{show: false}" @toggle="show = $event.detail">
    <x-toggle name="test" />
    
    <div x-show="show">
        <!-- input elements -->
    </div>
</div>

Now the parent will listen for the toggle event and update the data property.

This is the simplest possible way to handle inter-component communication in alphine.js.

But there's an option to handle it with states. Refer to this answer for more detailed description.

Upvotes: 1

Related Questions