Choices

This component is intended to be used to build complex selection interfaces for single and multiple values. It also supports async search when dealing with large lists.

Most of time you just need a simple Select component, which renders nice natively on every device.

Selection

By default, it will look up for:

  • $object->id for option value.
  • $object->name for option display label.
  • $object->avatar for avatar picture.

 
No results found.
Duncan

Iliana

Clementina

Lyla

 
No results found.
Duncan

Iliana

Clementina

Lyla

 
No results found.
eino81
Ebertchester

labadie.lenna
Brendantown

champlin.nick
Port Lenorefort

grant.hulda
West Harrison

It has custom options
@php
$users = $this->users;
@endphp
{{-- Notice `single` --}}
<x-choices label="Single" wire:model="user_id" :options="$users" single />
 
{{-- public array $users_multi_ids = []; --}}
<x-choices label="Multiple" wire:model="users_multi_ids" :options="$users" />
 
{{-- Custom options --}}
<x-choices
label="Custom options"
wire:model="user_custom_id"
:options="$users"
option-label="username"
option-sub-label="city.name"
option-avatar="other_avatar"
icon="o-users"
height="max-h-96" {{-- Default is `max-h-64` --}}
hint="It has custom options"
single />

Select All

This option only works for multiple and non-searchable exclusively.


 
Select all
Remove all
No results found.
Duncan

Iliana

Clementina

Lyla

 
Select all stuff
Delete all things
No results found.
Duncan

Iliana

Clementina

Lyla

@php
$users = $this->users;
@endphp
{{-- Notice `allow-all` --}}
<x-choices label="Multiple" wire:model="users_all_ids" :options="$users" allow-all />
 
<x-choices
label="Multiple"
wire:model="users_all2_ids"
:options="$users"
allow-all
allow-all-text="Select all stuff"
remove-all-text="Delete all things" />

Compact mode

This option only works for multiple and non-searchable exclusively.


selected
 
No results found.
Duncan

Iliana

Clementina

Lyla

stuff chosen
 
No results found.
Duncan

Iliana

Clementina

Lyla

@php
$users = $this->users;
@endphp
{{-- Notice `compact` --}}
<x-choices label="Compact" wire:model="users_compact_ids" :options="$users" compact />
 
<x-choices
label="Compact label"
wire:model="users_compact2_ids"
:options="$users"
compact
compact-text="stuff chosen" />

You can combine allow-all and compact

selected
 
Select all
Remove all
No results found.
Duncan

Iliana

Clementina

Lyla

@php
$users = $this->users;
@endphp
<x-choices
label="Select All + Compact"
wire:model="users_all_compact_ids"
:options="$users"
compact
allow-all />

Searchable

When dealing with large options list use searchable parameter. By default, it calls search() method to get fresh options while typing. You can change the method's name by using search-function parameter.


 
No results found.
Adelia

Alana

Alexanne

Ana

Arch

 
Ops! Nothing here ...
Adelia

Alana

Alexanne

Ana

Arch

@php
$usersSearchable = $this->usersSearchable;
$usersMultiSearchable = $this->usersMultiSearchable;
@endphp
{{-- Notice `searchable` + `single` --}}
<x-choices
label="Searchable + Single"
wire:model="user_searchable_id"
:options="$usersSearchable"
single
searchable />
 
{{-- Notice custom `search-function` --}}
<x-choices
label="Searchable + Multiple"
wire:model="users_multi_searchable_ids"
:options="$usersMultiSearchable"
search-function="searchMulti"
no-result-text="Ops! Nothing here ..."
searchable />

You must also consider displaying pre-selected items on list, when it first renders and while searching. There are many approaches to make it work, but here is an example for single search using Volt.

new class extends Component {
 
// Selected option
public ?int $user_searchable_id = null;
 
// Options list
public Collection $usersSearchable;
 
public function mount()
{
// Fill options when component first renders
$this->search();
}
 
// Also called as you type
public function search(string $value = '')
{
// Besides the search results, you must include on demand selected option
$selectedOption = User::where('id', $this->user_searchable_id)->orderBy('name')->get();
 
$this->usersSearchable = User::query()
->where('name', 'like', "%$value%")
->take(5)
->orderBy('name')
->get()
->merge($selectedOption); // <-- Adds selected option
}
}

Sometimes you don't want to hit a datasource on every keystroke. So, you can make use of debounce as described at Livewire docs for input fields.

Another approach is to use min-chars attribute to avoid hit search method itself until you have typed such amount of chars.


 
No results found.
@php
$usersSearchableMinChars = $this->usersSearchableMinChars;
@endphp
{{-- Notice `min-chars` and `debounce` --}}
<x-choices
label="Searchable + Single + Debounce + Min chars"
wire:model="user_searchable_min_chars_id"
:options="$usersSearchableMinChars"
search-function="searchMinChars"
debounce="300ms" {{-- Default is `250ms`--}}
min-chars="2" {{-- Default is `0`--}}
single
searchable />

Slots

You have full control on rendering items by using the @scope('item', $object) special blade directive. It injects the current $object from the loop's context and achieves the same behavior that you would expect from the Vue/React scoped slots.


 
No results found.
Duncan
Numquam accusantium voluptatibus similique fugit dolorem. A itaque explicabo voluptatibus.
eino81

Iliana
Minus cupiditate ut asperiores et. Vitae impedit esse id aut distinctio iure nesciunt aut. Quaerat minima rem officia enim. Pariatur sapiente hic necessitatibus dicta earum veritatis. Ullam dolores omnis earum vel.
labadie.lenna

Clementina
Nulla vero aliquid ut qui velit. Dolorem sed quae exercitationem quisquam aut magni. Culpa suscipit autem autem ducimus pariatur cupiditate.
champlin.nick

Lyla
Fugiat omnis commodi occaecati rem dolor. Nihil qui voluptatum consequatur ut. Maiores nobis ipsum dolore provident debitis.
grant.hulda

<div>
@php $users = $this->users @endphp
</div>
<x-choices label="Slots" wire:model="user_custom_slot_id" :options="$users" single>
@scope('item', $user)
<x-list-item :item="$user" sub-value="bio">
<x-slot:avatar>
<x-icon name="o-user" class="bg-orange-100 p-2 w-8 h8 rounded-full" />
</x-slot:avatar>
<x-slot:actions>
<x-badge :value="$user->username" />
</x-slot:actions>
</x-list-item>
@endscope
</x-choices>