- Making Columns
- Built-in searching
- Built-in sorting
- Built-in cell formatting
- Conditional columns
- User column selection
- Secondary Header Functionality
- Footer Functionality
- Misc. Functionality
Getting Started
Usage
Columns
The Query
Row
Bulk Actions
Filters
Customizing
Display
🎉 Enjoying this package? Consider sponsoring me on GitHub or buying me a beer.
This is the documentation for v1 but the latest version is v3. You can switch versions in the menu on the left/at the top. Check your current version with the following command:
composer show rappasoft/laravel-livewire-tables
Advanced Example
The DataTable plugin has many advanced features from bulk exporting, custom views, custom searching/sorting, filtering, column selection, drag & drop reordering, etc.
There will be sections of the wiki to go into these in detail, but this is an example of a table with a custom row, filters, and bulk exporting:
1<?php 2 3namespace App\Http\Livewire\Admin\User; 4 5use App\Domains\Auth\Models\User; 6use App\Domains\User\Exports\UserExport; 7use Illuminate\Database\Eloquent\Builder; 8use Rappasoft\LaravelLivewireTables\DataTableComponent; 9use Rappasoft\LaravelLivewireTables\Views\Column; 10use Rappasoft\LaravelLivewireTables\Views\Filter; 11 12class UsersTable extends DataTableComponent 13{ 14 15 public array $sortNames = [ 16 'email_verified_at' => 'Verified', 17 'two_factor_secret' => '2FA', 18 ]; 19 20 public array $filterNames = [ 21 'type' => 'User Type', 22 'verified' => 'E-mail Verified', 23 '2fa' => 'Two Factor Authentication', 24 ]; 25 26 public array $bulkActions = [ 27 'exportSelected' => 'Export', 28 ]; 29 30 protected string $pageName = 'users'; 31 protected string $tableName = 'users'; 32 33 public function exportSelected() 34 { 35 if ($this->selectedRowsQuery->count() > 0) { 36 return (new UserExport($this->selectedRowsQuery))->download($this->tableName.'.xlsx'); 37 } 38 39 // Not included in package, just an example. 40 $this->notify(__('You did not select any users to export.'), 'danger'); 41 } 42 43 public function filters(): array 44 { 45 return [ 46 'type' => Filter::make('User Type') 47 ->select([ 48 '' => 'Any', 49 User::TYPE_ADMIN => 'Administrators', 50 User::TYPE_USER => 'Users', 51 ]), 52 'active' => Filter::make('Active') 53 ->select([ 54 '' => 'Any', 55 'yes' => 'Yes', 56 'no' => 'No', 57 ]), 58 'verified' => Filter::make('E-mail Verified') 59 ->select([ 60 '' => 'Any', 61 'yes' => 'Yes', 62 'no' => 'No', 63 ]), 64 '2fa' => Filter::make('Two Factor Authentication') 65 ->select([ 66 '' => 'Any', 67 'enabled' => 'Enabled', 68 'disabled' => 'Disabled', 69 ]), 70 ]; 71 } 72 73 public function columns(): array 74 { 75 return [ 76 Column::make('Type') 77 ->sortable() 78 ->addClass('hidden md:table-cell'), 79 Column::make('Name') 80 ->sortable(), 81 Column::make('E-mail', 'email') 82 ->sortable(), 83 Column::make('Active') 84 ->sortable() 85 ->addClass('hidden md:table-cell'), 86 Column::make('Verified', 'email_verified_at') 87 ->sortable() 88 ->addClass('hidden md:table-cell'), 89 Column::make('2FA', 'two_factor_secret') 90 ->sortable() 91 ->addClass('hidden md:table-cell'), 92 Column::blank(), 93 ]; 94 } 95 96 public function query(): Builder 97 { 98 return User::query() 99 ->when($this->getFilter('search'), fn ($query, $search) => $query->search($search))100 ->when($this->getFilter('type'), fn ($query, $type) => $query->where('type', $type))101 ->when($this->getFilter('active'), fn ($query, $active) => $query->where('active', $active === 'yes'))102 ->when($this->getFilter('verified'), fn ($query, $verified) => $verified === 'yes' ? $query->whereNotNull('email_verified_at') : $query->whereNull('email_verified_at'))103 ->when($this->getFilter('2fa'), fn ($query, $twoFactor) => $twoFactor === 'enabled' ? $query->whereNotNull('two_factor_secret') : $query->whereNull('two_factor_secret'));104 }105 106 public function rowView(): string107 {108 return 'location.to.my.row.view';109 }110}
It's associated custom row:
row.blade.php
1<x-livewire-tables::table.cell class="hidden md:table-cell"> 2 <div> 3 @if ($row->isAdmin()) 4 <x-badges.success>{{ ucfirst($row->type) }}</x-badges.success> 5 @else 6 <x-badges.default>{{ ucfirst($row->type) }}</x-badges.default> 7 @endif 8 </div> 9</x-livewire-tables::table.cell>10 11<x-livewire-tables::table.cell>12 <div class="flex items-center">13 @if (Laravel\Jetstream\Jetstream::managesProfilePhotos())14 <div wire:key="profile-picture-{{ $row->id }}" class="flex-shrink-0 h-10 w-10">15 <img class="h-10 w-10 rounded-full" src="{{ $row->profile_photo_url }}" alt="{{ $row->name }}" />16 </div>17 @endif18 19 <div class="@if (Laravel\Jetstream\Jetstream::managesProfilePhotos()) ml-4 @endif">20 <div class="text-sm font-medium text-gray-900">21 {{ $row->name }}22 </div>23 24 @if($row->timezone)25 <div wire:key="timezone-{{ $row->id }}" class="text-sm text-gray-500">26 {{ str_replace('_', ' ', $row->timezone) }}27 </div>28 @endif29 </div>30 </div>31</x-livewire-tables::table.cell>32 33<x-livewire-tables::table.cell>34 <p class="text-blue-400 truncate">35 <a href="mailto:{{ $row->email }}" class="hover:underline">{{ $row->email }}</a>36 </p>37</x-livewire-tables::table.cell>38 39<x-livewire-tables::table.cell class="hidden md:table-cell">40 <div>41 @if ($row->isActive())42 <x-badges.success>@lang('Yes')</x-badges.success>43 @else44 <x-badges.danger>@lang('No')</x-badges.danger>45 @endif46 </div>47</x-livewire-tables::table.cell>48 49<x-livewire-tables::table.cell class="hidden md:table-cell">50 <div>51 @if ($row->isVerified())52 <x-badges.success>@lang('Yes')</x-badges.success>53 @else54 <x-badges.danger>@lang('No')</x-badges.danger>55 @endif56 </div>57</x-livewire-tables::table.cell>58 59<x-livewire-tables::table.cell class="hidden md:table-cell">60 <div>61 @if ($row->twoFactorEnabled())62 <x-badges.success>@lang('Enabled')</x-badges.success>63 @else64 <x-badges.danger>@lang('Disabled')</x-badges.danger>65 @endif66 </div>67</x-livewire-tables::table.cell>68 69<x-livewire-tables::table.cell>70 <a href="#" wire:click.prevent="manage({{ $row->id }})" class="text-primary-600 font-medium hover:text-primary-900">Manage</a>71</x-livewire-tables::table.cell>