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

CuriousBread's avatar

How to execute javascript when doing livewire click?

I want to execute a javascript code whenever I toggle a button. The javascript code that I want to execute is the intl-tel-input. The button switches the input from phone to email and email to phone. The input switching is working but the javascript code is not executed.

I tried using @push('scripts') and stack('scripts') but it didnt work.

0 likes
7 replies
LaryAI's avatar
Level 58

To execute JavaScript code when clicking a Livewire button, you can use the wire:click directive along with the @this directive to reference the Livewire component. Here's an example:

<button wire:click="toggleInput">Toggle Input</button>

@push('scripts')
    <script>
        document.addEventListener('livewire:load', function () {
            Livewire.on('inputToggled', function () {
                // Execute your JavaScript code here
                // For example, if you want to initialize intl-tel-input
                // you can call the initialization function
                initializeIntlTelInput();
            });
        });
    </script>
@endpush

In your Livewire component, you need to define the toggleInput method and emit an event to trigger the JavaScript code execution. Here's an example:

use Livewire\Component;

class YourComponent extends Component
{
    public $inputType = 'phone';

    public function toggleInput()
    {
        $this->inputType = ($this->inputType === 'phone') ? 'email' : 'phone';
        $this->emit('inputToggled');
    }

    // ...
}

Make sure to replace YourComponent with the actual name of your Livewire component.

This solution uses the Livewire JavaScript hooks to listen for the inputToggled event and execute the JavaScript code when the event is emitted.

Snapey's avatar

use regular onclick javascript listener and then fire the livewire event from within the javascript

CuriousBread's avatar

blade file

<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/js/intlTelInput.min.js"></script>
    <div class="flex items-center justify-between">
        @if(!$switch)
            <x-label for="phone" value="{{ __('Phone Number') }}" />
        @else
            <x-label for="email" value="{{ __('Email') }}" />
        @endif
        <div class="text-sm">
            <button class="font-semibold text-indigo-600 hover:text-indigo-500"
                    wire:click="$toggle('switch')" type="button"
            >
                @if(!$switch)
                    Continue with Email
                @else
                    Continue with Phone
                @endif
            </button>
        </div>
    </div>
@if(!$switch)
                    <x-input id="phone" type="tel" />
						<script>
								// code
						 </script>
                @else
						<x-input id="email" type="email" />
                @endif
CuriousBread's avatar

livewire component

<?php

namespace App\Livewire;

use Livewire\Component;

class EmailPhoneInputComponent extends Component
{
    public bool $switch = false;
    public function render()
    {
        return view('livewire.email-phone-input-component');
    }

    public function switchEmailOrPhone(): void
    {
        $this->switch = !$this->switch;
    }
}
Snapey's avatar

Your main problem will be that the phone input does not exist until you toggle and re-render the page

Why does this need to be in livewire at all? Keep both elements and toggle the visibility with a tiny bit of javascript

CuriousBread's avatar

@Snapey got it I'll just try and do it with javascript. But is their no other way to solve this through livewire?

Snapey's avatar

@CuriousBread you could control visibility with livewire rather than changing the dom but its a bit of a sledgehammer approach

what i mean is put one label and field in one div, and the other in another div and use @if ($switch) to set the hidden or block class on the div. Then your javascript can be permanently attached to the phone input rather than trying to attach it dynamically

Please or to participate in this conversation.