Skip to content

Instantly share code, notes, and snippets.

@vaporic
Forked from jackabox/AutoComplete.php
Created November 18, 2021 21:15
Show Gist options
  • Save vaporic/7294b8d3606baff7491aada45ca168bd to your computer and use it in GitHub Desktop.
Save vaporic/7294b8d3606baff7491aada45ca168bd to your computer and use it in GitHub Desktop.
Livewire Autocomplete Component
<div class="relative">
<x-label for="account" class="mb-2">Account Name</x-label>
<div class="relative">
<input
type="text"
class="relative w-full bg-white border border-gray-300 rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
placeholder="Search Accounts..."
wire:model="query"
wire:click="reset"
wire:keydown.escape="hideDropdown"
wire:keydown.tab="hideDropdown"
wire:keydown.Arrow-Up="decrementHighlight"
wire:keydown.Arrow-Down="incrementHighlight"
wire:keydown.enter.prevent="selectAccount"
/>
<input type="hidden" name="account" id="account" wire:model="selectedAccountID">
@if ($selectedAccount)
<a class="absolute cursor-pointer top-2 right-2 text-gray-500" wire:click="reset">
<svg xmlns="http://www.w3.org/2000/svg" width="24" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</a>
@endif
</div>
@if(!empty($query) && $selectedAccount == 0 && $showDropdown)
<div class="absolute z-10 bg-white mt-1 w-full border border-gray-300 rounded-md shadow-lg">
@if (!empty($accounts))
@foreach($accounts as $i => $account)
<a
wire:click="selectAccount({{ $i }})"
class="block py-1 px-2 text-sm cursor-pointer hover:bg-blue-50 {{ $highlightIndex === $i ? 'bg-blue-50' : '' }}"
>{{ $account['name'] }}</a>
@endforeach
@else
<span class="block py-1 px-2 text-sm">No results!</span>
@endif
</div>
@endif
</div>
<?php
namespace App\Http\Livewire;
use App\Models\Account;
use Livewire\Component;
class AccountAutocomplete extends Component
{
public $query= '';
public array $accounts = [];
public int $selectedAccount = 0;
public int $highlightIndex = 0;
public bool $showDropdown;
public function mount()
{
$this->reset();
}
public function reset(...$properties)
{
$this->accounts = [];
$this->highlightIndex = 0;
$this->query = '';
$this->selectedAccount = 0;
$this->showDropdown = true;
}
public function hideDropdown()
{
$this->showDropdown = false;
}
public function incrementHighlight()
{
if ($this->highlightIndex === count($this->accounts) - 1) {
$this->highlightIndex = 0;
return;
}
$this->highlightIndex++;
}
public function decrementHighlight()
{
if ($this->highlightIndex === 0) {
$this->highlightIndex = count($this->accounts) - 1;
return;
}
$this->highlightIndex--;
}
public function selectAccount($id = null)
{
$id = $id ?: $this->highlightIndex;
$account = $this->accounts[$id] ?? null;
if ($account) {
$this->showDropdown = true;
$this->query = $account['name'];
$this->selectedAccount = $account['id'];
}
}
public function updatedQuery()
{
$this->accounts = Account::where('name', 'like', '%' . $this->query. '%')
->take(5)
->get()
->toArray();
}
public function render()
{
return view('livewire.account-autocomplete');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment