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

Laravel Datatables Laravel Package

yajra/laravel-datatables

Complete Laravel DataTables installer bundling core plus plugins. Supports Laravel 13 and PHP 8.3+, built for DataTables 2.x with Editor, Buttons, and Select extensions. Includes docs and version compatibility guidance for Laravel 8–13.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require yajra/laravel-datatables:^13
    

    Publish config and assets (optional but recommended for customization):

    php artisan vendor:publish --provider="Yajra\DataTables\DataTablesServiceProvider"
    
  2. Register Service Providers (Laravel 5.5+): Add to config/app.php:

    Yajra\DataTables\DataTablesServiceProvider::class,
    Yajra\DataTables\ButtonsServiceProvider::class,
    Yajra\DataTables\FractalServiceProvider::class
    
  3. First Use Case: Create a route and controller method to handle DataTables requests:

    // routes/web.php
    Route::get('users/datatables', [UserController::class, 'datatables']);
    
    // app/Http/Controllers/UserController.php
    public function datatables()
    {
        return DataTables::of(User::query())
            ->addColumn('action', function ($user) {
                return '<button class="edit-btn">Edit</button>';
            })
            ->make(true);
    }
    
  4. Frontend Integration: Include DataTables CSS/JS (published assets or CDN) and initialize the table:

    <table id="users-table" class="display">
        <thead>
            <tr>
                <th>Name</th>
                <th>Email</th>
                <th>Actions</th>
            </tr>
        </thead>
    </table>
    
    <script>
    $(document).ready(function() {
        $('#users-table').DataTable({
            processing: true,
            serverSide: true,
            ajax: '{{ route("users.datatables") }}',
            columns: [
                { data: 'name', name: 'name' },
                { data: 'email', name: 'email' },
                { data: 'action', name: 'action', orderable: false, searchable: false }
            ]
        });
    });
    </script>
    

Where to Look First

  • Documentation: Laravel DataTables Docs (official, up-to-date).
  • Source Code: Focus on src/DataTables for core logic and src/Extensions for plugins (Buttons, Editor, etc.).
  • Config File: config/datatables.php for global settings (e.g., default response format, pagination).
  • Examples: Check the tests directory for real-world usage patterns.

Implementation Patterns

Core Workflows

1. Basic Eloquent Integration

// Simple table with Eloquent model
return DataTables::of(User::query())
    ->editColumn('name', 'name_edit') // Custom edit column
    ->addColumn('status', function ($user) {
        return $user->isActive ? 'Active' : 'Inactive';
    })
    ->make(true);

2. Query Builder for Complex Joins

// Multi-table queries with joins
return DataTables::of(
    DB::table('users')
        ->join('roles', 'users.role_id', '=', 'roles.id')
        ->select('users.*', 'roles.name as role_name')
)
->addColumn('full_role', function ($user) {
    return $user->role_name . ' (' . $user->name . ')';
})
->make(true);

3. Collection-Based Data

// For non-database collections (e.g., API responses)
$collection = collect([...]); // Your data source
return DataTables::of($collection)
    ->addIndexColumn() // Adds row numbers
    ->make(true);

4. Dynamic Column Filtering

// Filter columns based on request (e.g., for multi-tenancy)
$columns = ['name', 'email', 'created_at'];
return DataTables::of(User::query())
    ->filterColumn('name', function ($query) {
        return $query->where('name', 'like', '%' . request('name') . '%');
    })
    ->make(true);

Integration Tips

With Livewire

// Livewire component
public function datatables()
{
    return DataTables::of(User::query())
        ->addColumn('action', function ($user) {
            return '<button wire:click="edit({{ $user->id }})">Edit</button>';
        })
        ->make(true);
}

// Frontend
<div wire:ignore>
    <table id="users-table" class="display">
        <!-- Table structure -->
    </table>
</div>

<script>
$(document).ready(function() {
    $('#users-table').DataTable({
        processing: true,
        serverSide: true,
        ajax: '{{ route("users.datatables") }}',
        // ...
    });
});
</script>

With Inertia.js

// Controller
public function datatables()
{
    return Inertia::render('UsersTable', [
        'data' => DataTables::of(User::query())
            ->make(true)
            ->getData(),
    ]);
}

// Inertia.js Page
<DataTable
    :data="data"
    :columns="columns"
    :processing="true"
    server-side
/>

API-Only Responses

// Return raw JSON for SPAs
return DataTables::of(User::query())
    ->make(true)
    ->getData();

Custom Response Formatting

// Override default response structure
DataTables::of(User::query())
    ->addColumn('custom_field', function ($user) {
        return $user->customAttribute;
    })
    ->setTransformer(function ($query) {
        return $query->get(['id', 'name', 'custom_field']);
    })
    ->make(true);

Advanced Patterns

Bulk Actions with Buttons Extension

// Enable buttons extension
use Yajra\DataTables\Buttons;

// In controller
return DataTables::of(User::query())
    ->addColumn('action', function ($user) {
        return '<button class="delete-btn" data-id="' . $user->id . '">Delete</button>';
    })
    ->addActionColumn(['width' => '80px'])
    ->buttons([
        'export', 'print', 'reset', 'reload'
    ])
    ->make(true);

Editor for Inline Editing

// Enable editor
use Yajra\DataTables\Editor;

// In controller
return DataTables::of(User::query())
    ->editColumn('name', 'name_edit')
    ->editColumn('email', 'email_edit')
    ->editColumn('is_active', 'is_active_edit')
    ->make(true);

Select for Row Selection

// Enable select extension
use Yajra\DataTables\Select;

// In controller
return DataTables::of(User::query())
    ->selectColumn('id')
    ->make(true);

Custom Server-Side Processing

// Override server-side processing logic
DataTables::of(User::query())
    ->setServerSide(true)
    ->setServerSideCustom(function ($request, $query) {
        // Custom logic (e.g., multi-tenancy)
        $query->where('tenant_id', auth()->user()->tenant_id);
        return $query;
    })
    ->make(true);

Gotchas and Tips

Pitfalls

  1. CSRF Token Mismatch:

    • Issue: DataTables AJAX requests may fail with CSRF errors if not properly configured.
    • Fix: Ensure your routes are protected with @csrf in Blade or use VerifyCsrfToken middleware exclusions:
      // app/Http/Middleware/VerifyCsrfToken.php
      protected $except = [
          'users/datatables',
      ];
      
  2. Column Name Mismatches:

    • Issue: DataTables expects column names to match the database/collection exactly. Case sensitivity or aliasing can break sorting/filtering.
    • Fix: Use editColumn or addColumn to explicitly define column names:
      ->editColumn('user_name', 'name') // Maps 'name' DB column to 'user_name' in response
      
  3. Pagination Conflicts:

    • Issue: Default pagination settings may conflict with frontend expectations (e.g., 10 vs. 25 rows per page).
    • Fix: Configure globally in config/datatables.php or override per request:
      DataTables::of(User::query())
          ->setLength(50) // Override rows per page
          ->make(true);
      
  4. Memory Limits:

    • Issue: Large datasets or complex queries may hit PHP memory limits during server-side processing.
    • Fix: Optimize queries with select() or use chunking:
      DataTables::of(User::query()->select('id', 'name', 'email'))
          ->make(true);
      
  5. Caching Headers:

    • Issue: DataTables responses may not cache properly, leading to repeated server-side processing.
    • Fix: Add caching headers in your controller:
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai