kyslik/column-sortable
Add sortable table columns to Laravel (5.5–8) Eloquent listings. Provides Blade helpers to generate sort links with direction icons, supports configurable sortable fields, pagination-friendly URLs, and sorting on hasOne/belongsTo relations with optional aliases.
Installation:
composer require kyslik/column-sortable
Laravel 5.5+ auto-discovers the package. For older versions, manually add Kyslik\ColumnSortable\ColumnSortableServiceProvider to config/app.php.
Publish Config (optional):
php artisan vendor:publish --provider="Kyslik\ColumnSortable\ColumnSortableServiceProvider" --tag="config"
Model Integration:
Add the Sortable trait and define $sortable in your Eloquent model:
use Kyslik\ColumnSortable\Sortable;
class User extends Model
{
use Sortable;
public $sortable = ['id', 'name', 'email'];
}
First Use Case: In your controller, apply sorting to a paginated query:
$users = User::sortable()->paginate(10);
Access via URL: ?sort=name or ?sort=name:desc.
Controller:
public function index()
{
$users = User::sortable()->paginate(10); // Auto-detects `sort` query param
return view('users.index', compact('users'));
}
sortable('column') or sortable(['column' => 'desc']).?sort=detail.phone_number).Blade Views:
Use @sortablelink() for clickable sort headers:
@sortablelink('name', 'Username')
@sortablelink('created_at', 'Date', [], ['class' => 'text-muted'])
name).['filter' => 'active']).['class' => 'btn']).Pagination: Preserve query params in pagination links:
{!! $users->appends(\Request::except('page'))->render() !!}
Custom Sorting Logic: Override relation sorting in the model:
public function addressSortable($query, $direction)
{
return $query->join('details', 'users.id', '=', 'details.user_id')
->orderBy('address', $direction)
->select('users.*');
}
Use in Blade: @sortablelink('address').
Aliasing Columns:
Define $sortableAs in the model to bypass column checks:
public $sortableAs = ['nick_name'];
Query with: User::select(['name as nick_name'])->sortable(['nick_name'])->paginate(10).
Relation-Specific Sorting:
public function detail() { return $this->hasOne(UserDetail::class); }).@sortablelink('detail.phone_number').Dynamic Config:
Customize sort icons in config/columnsortable.php:
'columns' => [
'numeric' => ['rows' => ['id', 'created_at'], 'class' => 'fa-sort-numeric'],
'alpha' => ['rows' => ['name'], 'class' => 'fa-sort-alpha'],
],
Invalid Relation Names:
ColumnSortableException (code 1) if the relation doesn’t exist.public function user()).Malformed Sort URLs:
ColumnSortableException (code 0) if sort param isn’t column:direction (e.g., sort=name..desc).@sortablelink() for safe URLs.Column Existence Checks:
$sortable isn’t defined.$sortable in models to avoid Schema::hasColumn() calls.Pagination Conflicts:
appends() isn’t used.appends(\Request::except('page')) in Blade.Font Awesome Mismatch:
asc_suffix/desc_suffix in config to -up/-down.Log Sort Queries:
Temporarily add ->toSql() to debug generated queries:
$query = User::sortable()->toSql(); // Log this to check the SQL.
Test Relation Sorting: Verify relations are loaded:
$users = User::with('detail')->sortable(['detail.phone_number'])->get();
Check Config Overrides:
Ensure custom config values (e.g., uri_relation_column_separator) are published and updated.
Handle Exceptions:
Catch ColumnSortableException in controllers:
try {
$users = User::sortable()->paginate(10);
} catch (\Kyslik\ColumnSortable\Exceptions\ColumnSortableException $e) {
Log::error("Sorting failed: " . $e->getMessage());
return redirect()->back()->withError('Invalid sort parameter.');
}
Custom Blade Directives:
Extend @sortablelink() by creating a new Blade directive in a service provider:
Blade::directive('customSortable', function ($expression) {
return "<?php echo customSortableLogic($expression); ?>";
});
Dynamic $sortable:
Load $sortable dynamically based on user roles:
public function getSortable()
{
return $this->isAdmin() ? ['id', 'name', 'secret_column'] : ['id', 'name'];
}
Multi-Column Sorting:
Use Laravel’s orderByRaw for complex sorts (not natively supported):
public function multiSortable($query, $direction)
{
return $query->orderByRaw('FIELD(id, 1, 2, 3) DESC, name ASC');
}
API Integration: Return sort metadata in API responses:
return response()->json([
'data' => $users,
'sortable_columns' => $users->first()->getTableColumns(),
]);
How can I help you explore Laravel packages today?