Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Column Sortable Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. 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.

  2. Publish Config (optional):

    php artisan vendor:publish --provider="Kyslik\ColumnSortable\ColumnSortableServiceProvider" --tag="config"
    
  3. 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'];
    }
    
  4. 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.


Implementation Patterns

Core Workflow

  1. Controller:

    public function index()
    {
        $users = User::sortable()->paginate(10); // Auto-detects `sort` query param
        return view('users.index', compact('users'));
    }
    
    • Default Sorting: Override with sortable('column') or sortable(['column' => 'desc']).
    • Relation Sorting: Use dot notation (e.g., ?sort=detail.phone_number).
  2. Blade Views: Use @sortablelink() for clickable sort headers:

    @sortablelink('name', 'Username')
    @sortablelink('created_at', 'Date', [], ['class' => 'text-muted'])
    
    • Parameters:
      1. Column name (e.g., name).
      2. Display text (optional; defaults to column name).
      3. Query string parameters (e.g., ['filter' => 'active']).
      4. HTML attributes (e.g., ['class' => 'btn']).
  3. Pagination: Preserve query params in pagination links:

    {!! $users->appends(\Request::except('page'))->render() !!}
    

Advanced Patterns

  1. 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').

  2. 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).

  3. Relation-Specific Sorting:

    • HasOne/BelongsTo: Define relations in the model (e.g., public function detail() { return $this->hasOne(UserDetail::class); }).
    • Blade: @sortablelink('detail.phone_number').
  4. 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'],
    ],
    

Gotchas and Tips

Pitfalls

  1. Invalid Relation Names:

    • Error: ColumnSortableException (code 1) if the relation doesn’t exist.
    • Fix: Verify relation methods in the model (e.g., public function user()).
  2. Malformed Sort URLs:

    • Error: ColumnSortableException (code 0) if sort param isn’t column:direction (e.g., sort=name..desc).
    • Fix: Sanitize input or use @sortablelink() for safe URLs.
  3. Column Existence Checks:

    • Issue: Extra DB queries if $sortable isn’t defined.
    • Fix: Always define $sortable in models to avoid Schema::hasColumn() calls.
  4. Pagination Conflicts:

    • Issue: Sorting breaks pagination if appends() isn’t used.
    • Fix: Always include appends(\Request::except('page')) in Blade.
  5. Font Awesome Mismatch:

    • Issue: Icons don’t render if using FA5 but config is for FA4.
    • Fix: Update asc_suffix/desc_suffix in config to -up/-down.

Debugging Tips

  1. Log Sort Queries: Temporarily add ->toSql() to debug generated queries:

    $query = User::sortable()->toSql(); // Log this to check the SQL.
    
  2. Test Relation Sorting: Verify relations are loaded:

    $users = User::with('detail')->sortable(['detail.phone_number'])->get();
    
  3. Check Config Overrides: Ensure custom config values (e.g., uri_relation_column_separator) are published and updated.

  4. 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.');
    }
    

Extension Points

  1. 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); ?>";
    });
    
  2. Dynamic $sortable: Load $sortable dynamically based on user roles:

    public function getSortable()
    {
        return $this->isAdmin() ? ['id', 'name', 'secret_column'] : ['id', 'name'];
    }
    
  3. 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');
    }
    
  4. API Integration: Return sort metadata in API responses:

    return response()->json([
        'data' => $users,
        'sortable_columns' => $users->first()->getTableColumns(),
    ]);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui