Skip to content

Instantly share code, notes, and snippets.

@zerdotre
Last active May 16, 2025 07:23
Show Gist options
  • Select an option

  • Save zerdotre/e48b28df2ef8b4d7c9ce3db63f148487 to your computer and use it in GitHub Desktop.

Select an option

Save zerdotre/e48b28df2ef8b4d7c9ce3db63f148487 to your computer and use it in GitHub Desktop.
Single Livewire Volt file for Intl Tel Input.
<?php
namespace App\Livewire;
use Livewire\Attributes\On;
use Livewire\Attributes\Validate;
use Livewire\Component;
class ParentComponent extends Component
{
#[Validate('required|string|min:8')]
public string $phone = '';
public string $phoneValidationError = '';
#[On('phone-updated')]
public function handlePhoneUpdate($phone)
{
// Set phoneValidationError to empty str, Because update is only possible when valid.
$this->phoneValidationError = '';
$this->resetValidation('phone');
$this->phone = $phone;
}
#[On('phone-validation-error-updated')]
public function handlePhoneValidationError($message)
{
$this->phoneValidationError = $message;
$this->addError('phone', $this->phoneValidationError);
}
public function submit()
{
if (! empty($this->phoneValidationError)) {
$this->addError('phone', $this->phoneValidationError);
return;
}
$this->validate();
dd('submitted');
}
public function render()
{
return view('livewire.test');
}
}
<?php
use Livewire\Volt\Component;
new class extends Component {
public string $phone; // To use for initial value
public string $validationError = '';
}; ?>
<div>
<input wire:ignore type="tel" id="telInput" required class="flex-1 block w-full rounded-md border-zinc-300 focus:border-zinc-500 focus:ring-zinc-500 sm:text-sm" />
</div>
@assets
<script src="https://cdn.jsdelivr.net/npm/intl-tel-input@latest/build/js/intlTelInput.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/intl-tel-input@latest/build/css/intlTelInput.css" defer>
<style>.iti {width: 100%;}</style>
@endassets
@script
<script>
// This I found was needed too when doing something with GoogleMaps Js API in Livewire.
setTimeout(initi, 1);
function initi(){
window.input = document.querySelector("#telInput");
window.iti = intlTelInput(input, {
loadUtils: () => import("https://cdn.jsdelivr.net/npm/[email protected]/build/js/utils.js"),
initialCountry: "auto",
geoIpLookup: (success, failure) => {
fetch("https://ipapi.co/json")
.then((res) => res.json())
.then((data) => success(data.country_code))
.catch(() => failure());
}
});
// Set initial value if provided
if("{{ $phone }}") iti.setNumber("{{ $phone }}");
iti.promise.then(() => {
// Listen for changes
input.addEventListener("change", updateHandler, false); // input=live, change=blur
input.addEventListener("countrychange", updateHandler, false);
});
}
function updateHandler() {
const isValid = iti.isValidNumber();
// if input is not empty, validate.
if(input.value && !isValid) {
const error = iti.getValidationError(); // int (Errno)
const errorMessage = getError(error); // string (Message)
$wire.set('validationError', errorMessage);
$wire.dispatch('phone-validation-error-updated', { message: errorMessage });
} else {
$wire.set('validationError', '');
// Only possible when number isValid.
$wire.dispatch('phone-updated', { phone: iti.getNumber() });
}
}
function getError(error) {
switch (error) {
case intlTelInput.utils.validationError.TOO_SHORT: //2
return "The phone number is too short for the selected country";
case intlTelInput.utils.validationError.TOO_LONG: //3
return "The phone number is too long for the selected country";
case intlTelInput.utils.validationError.IS_POSSIBLE_LOCAL_ONLY: //4
return "The phone number is local only";
case intlTelInput.utils.validationError.INVALID_COUNTRY_CODE: //1
return "The selected country code is invalid";
case intlTelInput.utils.validationError.INVALID_LENGTH: //5
return "The phone number is of inValid length";
default:
return "There is something wrong with the phone number";
}
}
</script>
@endscript
@zerdotre
Copy link
Author

Ai couldnt properly implement this. There is a package for this but imo that is overkill. This one Volt file implements the tel input component properly.
tags: International Telephone Input , intl-tel-input.js, livewire, laravel, volt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment