Skip to content

Instantly share code, notes, and snippets.

@blockpc
Last active May 10, 2024 17:15
Show Gist options
  • Save blockpc/5878e8d02b1fa33a9e13ab912e9a6440 to your computer and use it in GitHub Desktop.
Save blockpc/5878e8d02b1fa33a9e13ab912e9a6440 to your computer and use it in GitHub Desktop.
select2 single for livewire 3 with tailwind and alpine

Select2 Livewire

Crear un componente select2.blade.php

@props(['name', 'title', 'options', 'empty_values' => 'Sin registros encontrados', 'selected_name' => null, 'selected_id' => null])

<div {{ $attributes->only('class')->merge(['class' => 'flex flex-col text-xs font-semibold']) }}>
    <label class="w-full lg:w-1/3 block font-medium text-xs md:text-sm" for="{{ $name }}">{{ title(__($title)) }}</label>
    <div class="w-full">
        <div class="w-full relative" x-data="{open:false}" x-on:click.away="open=false">

            <button type="button" class="inline-flex items-center px-2 py-1 text-xsbg-transparent border rounded border-gray-500 flex justify-between items-center w-full p-2" x-on:click="open=!open">
                <span class="float-left">{{ title(__($selected_name ?? $title)) }}</span>
                <div class="" :class="open ? 'rotate-180' : ''">
                    <x-bx-chevron-up class="w-4 h-4" />
                </div>
            </button>

            <div class="absolute z-10 w-full rounded-b shadow-md my-2 bg-gray-100 dark:bg-gray-700 text-dark border-l border-r border-b border-gray-500" x-show="open" x-cloak>
                <ul class="list-reset px-2 max-h-64 text-sm scrollbar-thin scrollbar-thumb-gray-400 scrollbar-track-gray-300 overflow-y-auto">
                    <li class="sticky top-0 bg-dark">
                        <input wire:model.live.debounce.500ms="{{ $attributes->get('search') }}" id="{{ $name }}" @keydown.enter="open = false; $event.target.blur()" type="text" class="block rounded-md shadow-md border-gray-300 dark:border-gray-500 bg-transparent text-xs md:text-sm h-8 w-full">
                    </li>
                    @forelse ($options as $option_id => $option_name)
                    <li class="" wire:click="{{ $attributes->get('click') }}({{ $option_id }})" x-on:click="open=false" id="option-{{$option_id}}">
                        <div class="p-2 w-full hover:bg-gray-300 hover:dark:bg-gray-600 flex justify-between cursor-pointer text-xs">
                            <span>{{$option_name}}</span>
                            @if ($option_id == $selected_id)
                            <x-bx-check class="w-4 h-4" />
                            @endif
                        </div>
                    </li>
                    @empty
                    <li x-on:click="open=false">
                        <p class="p-2 block dark:text-red-400 text-red-800 hover:bg-red-200 cursor-pointer">{{ $empty_values }}</p>
                    </li>
                    @endforelse
                </ul>
            </div>
        </div>
    </div>
</div>

Y asociar los valores que se necesitan para el componente. una funcion para el el evento click select_option una variable search que sirva para buscar. una variable selected_name que persista el nombre seleccionado. una variable selected_id que persista el id seleccionado.

final class YourComponent extends Component
{
	public $search;
    public $selected_name;
    public $selected_id;
	
	public function render()
    {
        return view('livewire.your-component');
    }

    public function select_option($option_id)
    {
        $this->selected_name = null;
        $this->selected_id = null;
        if ( $option_id ) {
            $this->selected_name = $this->users[$option_id];
            $this->selected_id = $option_id;
        }
    }
	
	#[Computed()]
    public function users()
    {
        return User::query()
                    ->when($this->search, function ($query) {
                        // aqui haces la busqueda
                    })
                    ->get()
                    ->sortBy('name')
                    ->pluck('name', 'id')
                    ->toArray();
    }
}

en la vista del componente your-component.blade.php

<div>

	<x-select2 
		class="" 
		name="lista_de_usuarios" 
		title="usuarios" 
		:options="$this->users" 
		search="search" 
		click="select_option" 
		selected_name="{{ $selected_name }}" 
		selected_id="{{ $selected_id }}" 
	/>

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