Building a Search Drop Down Component with Laravel Livewire

under Laravel

Laravel Livewire allows you to build interactive web applications without any custom JavaScript. It's built around the Laravel framework.

Watch the video below for a step-by-step guide on how you can use Laravel Livewire to build an interactive search drop down component, without any custom JavaScript.

PHP component file:

1<?php
2 
3namespace App\Http\Livewire;
4 
5use App\Contact;
6use Livewire\Component;
7 
8class ContactSearchBar extends Component
9{
10 public $query;
11 public $contacts;
12 public $highlightIndex;
13 
14 public function mount()
15 {
16 $this->reset();
17 }
18 
19 public function reset()
20 {
21 $this->query = '';
22 $this->contacts = [];
23 $this->highlightIndex = 0;
24 }
25 
26 public function incrementHighlight()
27 {
28 if ($this->highlightIndex === count($this->contacts) - 1) {
29 $this->highlightIndex = 0;
30 return;
31 }
32 $this->highlightIndex++;
33 }
34 
35 public function decrementHighlight()
36 {
37 if ($this->highlightIndex === 0) {
38 $this->highlightIndex = count($this->contacts) - 1;
39 return;
40 }
41 $this->highlightIndex--;
42 }
43 
44 public function selectContact()
45 {
46 $contact = $this->contacts[$this->highlightIndex] ?? null;
47 if ($contact) {
48 $this->redirect(route('show-contact', $contact['id']));
49 }
50 }
51 
52 public function updatedQuery()
53 {
54 $this->contacts = Contact::where('name', 'like', '%' . $this->query . '%')
55 ->get()
56 ->toArray();
57 }
58 
59 public function render()
60 {
61 return view('livewire.contact-search-bar');
62 }
63}

Blade view:

1<div class="relative">
2 <input
3 type="text"
4 class="form-input"
5 placeholder="Search Contacts..."
6 wire:model="query"
7 wire:keydown.escape="reset"
8 wire:keydown.tab="reset"
9 wire:keydown.arrow-up="decrementHighlight"
10 wire:keydown.arrow-down="incrementHighlight"
11 wire:keydown.enter="selectContact"
12 />
13 
14 <div wire:loading class="absolute z-10 w-full bg-white rounded-t-none shadow-lg list-group">
15 <div class="list-item">Searching...</div>
16 </div>
17 
18 @if(!empty($query))
19 <div class="fixed top-0 bottom-0 left-0 right-0" wire:click="reset"></div>
20 
21 <div class="absolute z-10 w-full bg-white rounded-t-none shadow-lg list-group">
22 @if(!empty($contacts))
23 @foreach($contacts as $i => $contact)
24 <a
25 href="{{ route('show-contact', $contact['id']) }}"
26 class="list-item {{ $highlightIndex === $i ? 'highlight' : '' }}"
27 >{{ $contact['name'] }}</a>
28 @endforeach
29 @else
30 <div class="list-item">No results!</div>
31 @endif
32 </div>
33 @endif
34</div>

Thanks for reading this article!

Hopefully you found this article useful! If you did, share it on Twitter!

Found an issue with the article? Submit your edits against the repository.