j-j-t-m/laravel-select2
Componente Blade para Laravel que integra Select2 com busca AJAX, paginação/rolagem infinita e selects dependentes (cascata). Configuração centralizada via arquivo lists.php, pronto para grandes volumes de dados e fácil de reutilizar nas views.
Installation:
composer require J-J-T-M/laravel-select2
php artisan vendor:publish --provider="JJTM\Select2\Select2ServiceProvider"
config/select2.php) and Blade components.Configure:
Edit config/select2.php to define your dynamic lists (e.g., users, cities). Example:
'lists' => [
'users' => [
'model' => \App\Models\User::class,
'search_fields' => ['name', 'email'],
'order_by' => 'name',
],
'cities' => [
'model' => \App\Models\City::class,
'search_fields' => ['name'],
'order_by' => 'name',
'parent_field' => 'state_id', // For dependent selects
],
],
First Use Case: In a Blade view, use the component with minimal attributes:
<x-select2
name="user_id"
list="users"
placeholder="Select a user..."
/>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
Basic Dynamic Select:
<x-select2
name="product_id"
list="products"
placeholder="Search products..."
min-input-length="2" <!-- Triggers search after 2 chars -->
/>
select2/{list}) to handle AJAX requests. No manual route definition needed.Dependent Selects (Cascading):
config/select2.php:
'states' => [
'model' => \App\Models\State::class,
'search_fields' => ['name'],
],
'cities' => [
'model' => \App\Models\City::class,
'search_fields' => ['name'],
'parent_field' => 'state_id', // Links to state_id in City model
],
<x-select2
name="state_id"
list="states"
placeholder="Select a state..."
/>
<x-select2
name="city_id"
list="cities"
placeholder="Select a city..."
parent-field="state_id" <!-- Links to state_id input -->
/>
Customizing Responses:
Override the default JSON response format by publishing the Select2Response class:
php artisan vendor:publish --tag="select2-responses"
app/Select2/Responses/CustomSelect2Response.php to modify how data is formatted.Integration with Forms:
Rule::exists('users', 'id')).<x-select2
name="user_ids[]"
list="users"
multiple
/>
Pagination:
config/select2.php):
'pagination' => [
'enabled' => true,
'per_page' => 10,
],
ajax options in the component’s options attribute (JSON string).Laravel Mix/Webpack: Ensure Select2 CSS is included in your build:
// resources/js/app.js
import 'select2/dist/css/select2.min.css';
Livewire/Alpine.js: Use the component inside Livewire/Alpine components by passing dynamic data via props:
<x-select2
name="dynamic_list"
list="{{ $dynamicListConfig }}"
wire:model="selectedValue"
/>
API Resources:
Extend the default response by modifying the Select2Resource (published via php artisan vendor:publish --tag="select2-resources").
Route Conflicts:
select2/{list}). Ensure no naming collisions with existing routes.routes/web.php if needed:
Route::get('/custom-select2/{list}', [\JJTM\Select2\Http\Controllers\Select2Controller::class, 'index']);
CSRF Token Mismatch:
select2 route.App\Http\Middleware\VerifyCsrfToken:
protected $except = [
'select2/*',
];
Model Relationships:
parent_field in config/select2.php matches the foreign key in your database.php artisan tinker to verify relationships:
$state = App\Models\State::find(1);
$state->cities; // Should return a collection
Performance with Large Datasets:
'pagination' => [
'enabled' => false, // Disable if list < 100 items
],
search_fields for faster queries.Select2 Version Mismatch:
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
AJAX Requests:
/select2/{list}). Check for:
q (search query) and page (pagination) parameters.{results: [...], pagination: {...}}).Blade Component Errors:
list attribute matches a key in config/select2.php.{{ dd($this->listConfig) }} inside the component to debug config loading.JavaScript Errors:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
$ is not defined errors if jQuery isn’t loaded.Customizing the Component:
php artisan vendor:publish --tag="select2-views"
resources/views/vendor/select2/select2.blade.php to add custom markup or logic.Adding New Lists Dynamically:
Select2Manager facade to register lists programmatically:
use JJTM\Select2\Facades\Select2Manager;
Select2Manager::addList('dynamic_users', [
'model' => \App\Models\User::class,
'search_fields' => ['name', 'email'],
]);
boot() method.Extending the Controller:
Route::get('/custom-select2/{list}', [App\Http\Controllers\CustomSelect2Controller::class, 'index']);
\JJTM\Select2\Http\Controllers\Select2Controller for custom logic.Localization:
php artisan vendor:publish --tag="select2-lang"
resources/lang/{locale}/select2.php and override the default strings.Reuse Config Across Projects:
Share config/select2.php and Blade components between projects using Laravel’s package development features.
Type Safety:
Add PHPStan or Psalm rules to enforce type safety for list configurations:
# phpstan.neon
parameters:
select2_l
How can I help you explore Laravel packages today?