Skip to content

Instantly share code, notes, and snippets.

@owenconti
Created May 19, 2020 01:41
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save owenconti/fb366a7a928395bc003efb98042be17e to your computer and use it in GitHub Desktop.
Save owenconti/fb366a7a928395bc003efb98042be17e to your computer and use it in GitHub Desktop.
Building a search drop down component with Laravel Livewire
<?php
namespace App\Http\Livewire;
use App\Contact;
use Livewire\Component;
class ContactSearchBar extends Component
{
public $query;
public $contacts;
public $highlightIndex;
public function mount()
{
$this->reset();
}
public function reset()
{
$this->query = '';
$this->contacts = [];
$this->highlightIndex = 0;
}
public function incrementHighlight()
{
if ($this->highlightIndex === count($this->contacts) - 1) {
$this->highlightIndex = 0;
return;
}
$this->highlightIndex++;
}
public function decrementHighlight()
{
if ($this->highlightIndex === 0) {
$this->highlightIndex = count($this->contacts) - 1;
return;
}
$this->highlightIndex--;
}
public function selectContact()
{
$contact = $this->contacts[$this->highlightIndex] ?? null;
if ($contact) {
$this->redirect(route('show-contact', $contact['id']));
}
}
public function updatedQuery()
{
$this->contacts = Contact::where('name', 'like', '%' . $this->query . '%')
->get()
->toArray();
}
public function render()
{
return view('livewire.contact-search-bar');
}
}
<div class="relative">
<input
type="text"
class="form-input"
placeholder="Search Contacts..."
wire:model="query"
wire:keydown.escape="reset"
wire:keydown.tab="reset"
wire:keydown.ArrowUp="decrementHighlight"
wire:keydown.ArrowDown="incrementHighlight"
wire:keydown.enter="selectContact"
/>
<div wire:loading class="absolute z-10 list-group bg-white w-full rounded-t-none shadow-lg">
<div class="list-item">Searching...</div>
</div>
@if(!empty($query))
<div class="fixed top-0 right-0 bottom-0 left-0" wire:click="reset"></div>
<div class="absolute z-10 list-group bg-white w-full rounded-t-none shadow-lg">
@if(!empty($contacts))
@foreach($contacts as $i => $contact)
<a
href="{{ route('show-contact', $contact['id']) }}"
class="list-item {{ $highlightIndex === $i ? 'highlight' : '' }}"
>{{ $contact['name'] }}</a>
@endforeach
@else
<div class="list-item">No results!</div>
@endif
</div>
@endif
</div>
@eugenefvdm
Copy link

I'm dying to understand where the list-item and list-group classes are coming from!

@owenconti
Copy link
Author

I'm dying to understand where the list-item and list-group classes are coming from!

I think these are them:

.list-group {
    @apply border border-gray-300 border-t-0 rounded-lg overflow-hidden;
}
.list-item {
    @apply text-gray-800 block p-3 font-bold border-t border-gray-300;
}
.list-item:nth-child(even) {
    @apply bg-gray-100;
}
a.list-item:hover,
.list-item.highlight {
    @apply bg-blue-100;
}

@johnpatrix
Copy link

wire:keydown.Arrow-Up="decrementHighlight"
wire:keydown.Arrow-Down="incrementHighlight"
I had to use this "-" for arrowkey press detection.
I am not sure if it is because of version difference or because of my OS- Ubuntu
"livewire/livewire": "^2.4"
"laravel/framework": "^8.40"
Hope someone will find it helpful!
Thank you for the code,

@owenconti
Copy link
Author

@johnpatrix most likely the version change, my article is definitely out of date

@hofmannsven
Copy link

@johnpatrix Thanks a lot! Adding the dash worked for me (Livewire version ^2.5).

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