Last active
October 25, 2024 19:29
-
-
Save mithicher/9944232624cbad4b1cb5d3d2cac87a97 to your computer and use it in GitHub Desktop.
Tom Select Livewire Blade Component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Component Usage | |
// Data for options | |
$users = \App\User::limit(6)->get()->transform(fn($user) => [ | |
'id' => $user->id, | |
'title' => $user->name, | |
'subtitle' => $user->email | |
]); | |
// Usage in view | |
<x-tom-select | |
id="testUser" | |
name="testUser" | |
wire:model="testUser" | |
:options="$users" | |
placeholder="Pick a user" | |
items="{{ $testUser }}" // for multiselect edit eg. 1,2,3 comma separated ids | |
// multiple // enable for multiple select | |
/> | |
*/ | |
@props([ | |
'options' => [], | |
'items' => null | |
]) | |
<div wire:ignore> | |
<select | |
x-data="{ | |
tomSelectInstance: null, | |
options: {{ collect($options) }}, | |
items: [{{ $items }}], | |
renderTemplate(data, escape) { | |
return `<div class='flex items-center'> | |
<span class='mr-3 w-8 h-8 rounded-full bg-gray-100'><img src='https://avatars.dicebear.com/api/initials/${escape(data.title)}.svg' class='w-8 h-8 rounded-full'/></span> | |
<div><span class='block font-medium text-gray-700'>${escape(data.title)}</span> | |
<span class='block text-gray-500'>${escape(data.subtitle)}</span></div> | |
</div>`; | |
}, | |
itemTemplate(data, escape) { | |
return `<div> | |
<span class='block font-medium text-gray-700'>${escape(data.title)}</span> | |
</div>`; | |
} | |
}" | |
x-init="tomSelectInstance = new TomSelect($refs.input, { | |
valueField: 'id', | |
labelField: 'title', | |
searchField: 'title', | |
options: options, | |
items: items, | |
@if (! empty($items) && ! $attributes->has('multiple')) | |
placeholder: undefined, | |
@endif | |
render: { | |
option: renderTemplate, | |
item: itemTemplate | |
} | |
});" | |
x-ref="input" | |
x-cloak | |
{{ $attributes }} | |
placeholder="Pick some links..."></select> | |
</div> | |
@once | |
@push('styles') | |
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/tom-select.css" rel="stylesheet"> | |
<style> | |
.ts-input { | |
padding: 10px 8px; | |
border-radius: 0.5rem; | |
border-color: rgba(209, 213, 219, 1.0); | |
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); | |
} | |
.ts-input.focus { | |
outline: 2px solid transparent; | |
outline-offset: 2px; | |
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), 0 0 0 3px rgba(199, 210, 254, 0.5); | |
border-color: rgba(165, 180, 252, 1.0); | |
} | |
.ts-input.dropdown-active { | |
border-radius: 0.5rem 0.5rem 0 0; | |
} | |
.ts-dropdown { | |
margin: -5px 0 0 0; | |
border-radius: 0 0 0.5rem 0.5rem; | |
padding-bottom: 4px; | |
} | |
.ts-control.single .ts-input:after { | |
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' viewBox='0 0 24 24' stroke='%239CA3AF'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M8 9l4-4 4 4m0 6l-4 4-4-4' /%3E%3C/svg%3E"); | |
display: block; | |
position: absolute; | |
top: 10px; | |
right: 8px; | |
width: 24px; | |
height: 24px; | |
border: none; | |
} | |
</style> | |
@endpush | |
@push('scripts') | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/tom-select.complete.min.js"></script> | |
@endpush | |
@endonce |
Just a lil late, by uhh 2 years. Had a ton of problems, with tom-select but this managed to send me in the correct direction thanks :)
I had written some code to allow for real-time updating of the item list and the selected value so that you can change those in php / server side and have it reflect in the selection.
The fork is here if anyone comes across this and need a more documented and implemented solution https://gist.github.com/CallumCarmicheal/3bcbfb178443c9a11c673be83530ac8d
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@thumbtech use
{{ collect($selectedItems) }}
instead of{{ json_encode($selectedItems) }}
. It works well for nested objects.