π The best and most practical alternative to Select2 for Laravel Livewire - Native searchable select component with database integration, no jQuery dependency!
composer require fyyyn1210/wire-select<livewire:wire-select-box
table-name="users"
field-name="user_id"
label="Select User" />That's it! π Your searchable select is ready!
- Laravel 10.x or 11.x
- Livewire 3.x
- PHP 8.1+
# Via Composer (Recommended)
composer require fyyyn1210/wire-select
# Clear cache after installation
php artisan config:clear
php artisan view:clear# Check if package is loaded
composer show fyyyn1210/wire-select# Publish config file for customization
php artisan vendor:publish --provider="Fyyyn1210\WireSelect\WireSelectServiceProvider" --tag="config"
# This creates: config/wire-select.php# Publish views for custom styling
php artisan vendor:publish --provider="Fyyyn1210\WireSelect\WireSelectServiceProvider" --tag="views"
# This creates: resources/views/vendor/wire-select/# Publish CSS/JS assets
php artisan vendor:publish --provider="Fyyyn1210\WireSelect\WireSelectServiceProvider" --tag="assets"
# This creates: public/vendor/wire-select/// database/migrations/create_users_table.php
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->timestamps();
});// database/seeders/UserSeeder.php
User::factory()->count(50)->create();// app/Livewire/UserForm.php
<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\Attributes\On;
class UserForm extends Component
{
public $user_id;
public $formData = [];
#[On('selectionChanged')]
public function handleUserSelection($data)
{
if ($data['field'] === 'user_id') {
$this->user_id = $data['value'];
}
}
public function save()
{
$this->validate([
'user_id' => 'required|exists:users,id'
]);
// Save logic here
}
public function render()
{
return view('livewire.user-form');
}
}<!-- resources/views/livewire/user-form.blade.php -->
<div>
<form wire:submit="save">
<livewire:wire-select-box
table-name="users"
search-column="name"
key-column="id"
value-column="name"
field-name="user_id"
label="Select User"
placeholder="Type to search users..."
:required="true" />
@error('user_id')
<span class="text-danger">{{ $message }}</span>
@enderror
<button type="submit" class="btn btn-primary">Save</button>
</form>
@if($user_id)
<div class="alert alert-success">
Selected User ID: {{ $user_id }}
</div>
@endif
</div>// app/Livewire/CategoryForm.php
<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\Attributes\On;
class CategoryForm extends Component
{
public $categories = [
1 => 'Technology',
2 => 'Business',
3 => 'Science',
4 => 'Health',
5 => 'Education'
];
public $selected_category;
#[On('selectionChanged')]
public function handleSelection($data)
{
if ($data['field'] === 'category') {
$this->selected_category = $data['value'];
}
}
public function render()
{
return view('livewire.category-form');
}
}<!-- resources/views/livewire/category-form.blade.php -->
<div>
<livewire:wire-select-box
:items="$categories"
field-name="category"
label="Select Category"
placeholder="Search categories..."
icon="ki-category"
:selected-value="$selected_category" />
</div>// app/Livewire/ProductForm.php
<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\Attributes\On;
class ProductForm extends Component
{
public $product_id;
public $category_id = 1; // Pre-selected category
#[On('selectionChanged')]
public function handleProductSelection($data)
{
if ($data['field'] === 'product_id') {
$this->product_id = $data['value'];
}
}
public function render()
{
return view('livewire.product-form');
}
}<!-- resources/views/livewire/product-form.blade.php -->
<div>
<livewire:wire-select-box
table-name="products"
search-column="name"
key-column="id"
value-column="name"
field-name="product_id"
label="Select Active Product"
:condition="['status' => 'active', 'category_id' => $category_id]"
placeholder="Search products..."
icon="ki-box"
:limit="20"
max-height="300px" />
</div><?php
return [
'defaults' => [
'placeholder' => 'Search...',
'empty_message' => 'No data found',
'max_height' => '250px',
'limit' => 10,
'icon' => 'ki-search',
'icon_path' => 2,
'required' => true,
],
'css' => [
'container' => 'mb-3',
'label' => 'form-label fw-semibold',
'input' => 'form-control',
'dropdown' => 'border rounded shadow-sm',
]
];<livewire:wire-select-box
{{-- Data Source --}}
:items="$array_data" <!-- Static array data -->
table-name="table_name" <!-- Database table -->
search-column="column_name" <!-- Column to search -->
key-column="id" <!-- Key column -->
value-column="name" <!-- Display column -->
:condition="['status' => 'active']" <!-- WHERE conditions -->
{{-- Behavior --}}
field-name="field_name" <!-- Field identifier -->
:selected-value="$value" <!-- Pre-selected value -->
:limit="20" <!-- Max results -->
:show-init="true" <!-- Show initial data -->
{{-- Appearance --}}
label="Select Item" <!-- Label text -->
placeholder="Search..." <!-- Placeholder text -->
icon="ki-search" <!-- Icon class -->
:icon-path="2" <!-- Icon paths count -->
max-height="300px" <!-- Max dropdown height -->
empty-message="No data found" <!-- Empty state message -->
{{-- States --}}
:required="true" <!-- Required field -->
:disabled="false" <!-- Disabled state -->
/><!-- Old Select2 HTML -->
<div class="form-group">
<label>Select User</label>
<select id="user-select" class="form-control select2" data-placeholder="Choose user...">
<option value=""></option>
</select>
</div>
<script>
$(document).ready(function() {
$('#user-select').select2({
ajax: {
url: '{{ route("users.search") }}',
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term,
page: params.page
};
},
processResults: function (data, params) {
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
placeholder: 'Search for users',
minimumInputLength: 1,
templateResult: formatUser,
templateSelection: formatUserSelection
});
$('#user-select').on('select2:select', function (e) {
var data = e.params.data;
@this.set('user_id', data.id);
});
});
function formatUser (user) {
if (user.loading) {
return user.text;
}
return $('<span>' + user.name + ' (' + user.email + ')</span>');
}
function formatUserSelection (user) {
return user.name || user.text;
}
</script>// Old API Route
Route::get('/users/search', function (Request $request) {
$users = User::where('name', 'like', '%' . $request->q . '%')
->orWhere('email', 'like', '%' . $request->q . '%')
->paginate(30);
return response()->json([
'items' => $users->items(),
'total_count' => $users->total()
]);
});<!-- New Livewire Component - ONE LINE! -->
<livewire:wire-select-box
table-name="users"
search-column="name"
field-name="user_id"
label="Select User"
placeholder="Search for users..." />// Handle selection in your Livewire component
#[On('selectionChanged')]
public function handleUserSelection($data)
{
if ($data['field'] === 'user_id') {
$this->user_id = $data['value'];
}
}Lines of code reduced: 60+ β 2 lines!
# Error: Component [wire-select-box] not found
# Solution: Clear cache
php artisan config:clear
php artisan view:clear
composer dump-autoload# Make sure Bootstrap/your CSS framework is loaded
# Or publish and customize the views
php artisan vendor:publish --provider="Fyyyn1210\WireSelect\WireSelectServiceProvider" --tag="views"// Make sure your database table exists and has the specified columns
// Check your .env database configuration
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database
DB_USERNAME=your_username
DB_PASSWORD=your_password// Make sure you're using the correct event listener
use Livewire\Attributes\On;
#[On('selectionChanged')]
public function handleSelection($data)
{
// Your logic here
}<!-- Add debug info to see what's happening -->
<livewire:wire-select-box
table-name="users"
field-name="user_id"
label="Select User" />
<!-- Debug output -->
@if(config('app.debug'))
<div class="mt-2 small text-muted">
Selected: {{ $user_id ?? 'None' }}
</div>
@endifYour Livewire Searchable Select is now installed and ready to use. Start with a simple example and gradually explore more advanced features.
Need help? Check our GitHub Issues or Discussions.