Skip to content

Instantly share code, notes, and snippets.

@jhonoryza
Forked from mithicher/tom-select.blade.php
Last active November 13, 2021 03:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhonoryza/7c2bd723b9aca69e7fcfbb203064df62 to your computer and use it in GitHub Desktop.
Save jhonoryza/7c2bd723b9aca69e7fcfbb203064df62 to your computer and use it in GitHub Desktop.
Tom Select Livewire Blade Component

tom select plugin https://tom-select.js.org/

Usage

/* 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
 />
 
 */

Blade Component


@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/tom-select@1.1/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/tom-select@1.1/dist/js/tom-select.complete.min.js"></script>
	@endpush
@endonce
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment