Laravel Livewire Tables Documentation

🎉 Enjoying this package? Consider sponsoring me on GitHub or buying me a beer.

This is the documentation for v3. You can switch versions in the menu at the top. Check your current version with the following command:

composer show rappasoft/laravel-livewire-tables

Anonymous Columns


Sometimes you may need an "anonymous column", or a column that isn't bound to any column in your database. A common example of this would be an "actions" column at the end of every row with actions of "view", "edit", and/or "delete". Though, it doesn't have to be an action column, it could be anything.

By using an anonymous column, you take full control by using your own view component. So if you find the LinkColumn, ImageColumn, or any of the other columns too restrictive for your needs, then an anonymous column may be what you need.

To make an anonymous column, you create an anonymous function that returns a view into the label() method, which will remove the requirement for a database column. Thus, making it "anonymous". You can also pass variables to the view by chaining the with() method onto the view() method that gets returned by the anonymous function into the label(). So you can either pass specific values, or the whole row itself. Lastly, chain the html() method to the column so it can render your view component as html.

Example Action Column

Here is an example of an action column using FontAwesome icons for the "view", "edit", and "delete" actions.

In your DataTableComponent:

3namespace App\Livewire;
5use App\Models\User;
6use Rappasoft\LaravelLivewireTables\DataTableComponent;
7use Rappasoft\LaravelLivewireTables\Views\Column;
9class UserTable extends DataTableComponent
11 protected $model = User::class;
13 public function configure(): void
14 {
15 $this->setPrimaryKey('id');
16 $this->setDefaultSort('id', 'asc');
17 }
19 public function columns(): array
20 {
21 return [
22 Column::make('id', 'id')
23 ->sortable()
24 ->searchable(),
25 Column::make('Name', 'name')
26 ->sortable()
27 ->searchable(),
28 Column::make('Email', 'email')
29 ->sortable()
30 ->searchable(),
31 Column::make('Registered', 'created_at')
32 ->sortable(),
33 Column::make('Updated', 'updated_at')
34 ->sortable(),
35 Column::make('Last Login', 'last_login_at')
36 ->sortable(),
38 Column::make('Action')
39 ->label(
40 fn ($row, Column $column) => view('components.livewire.datatables.action-column')->with(
41 [
42 'viewLink' => route('users.view', $row),
43 'editLink' => route('users.edit', $row),
44 'deleteLink' => route('users.delete', $row),
45 ]
46 )
47 )->html(),
48 ];
49 }

NOTE: You don't have to pass individual properties like viewLink and so on. You could simply pass the whole record to your view and handle it however you need within the view file. Example:

2 ->label(
3 fn ($row, Column $column) => view('components.livewire.datatables.action-column')->with([
4 'user' => $row,
5 ])
6 )->html(),

Now in your component's view file you can do something like this:

2 @isset ( $viewLink )
3 <a href="{{ $viewLink }}"><i class="fa-solid fa-eye me-2"></i></a>
4 @endif
6 @isset ( $editLink )
7 <a href="{{ $editLink }}"><i class="fa-solid fa-pen-to-square me-2"></i></a>
8 @endif
10 @isset ( $deleteLink )
11 <form
12 action="{{ $deleteLink }}"
13 class="d-inline"
14 method="POST"
15 x-data
16 @submit.prevent="if (confirm('Are you sure you want to delete this user?')) $el.submit()"
17 >
18 @method('DELETE')
19 @csrf
20 <button type="submit" class="btn btn-link">
21 <i class="fa-solid fa-trash"></i>
22 </button>
23 </form>
24 @endif

Or, if you passed the whole record, you could use:

1<a href="{{ route('users.view', $user) }}"><i class="fa-solid fa-eye me-2"></i></a>


The final result can look something like this: