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

Introduction

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 string or 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, you may chain the html() method to the column so it can render your view component as html.

Example Column Using a String

Here is an example of using a label to return the "Full Name" of a User. Note that as we are using a label(), you must add any related fields into the setAdditionalSelects() method in the configure() method.

In this case, we are adding the "forename" and "surname" field from the database to the computed set of selects, then in the label, we are combining those, while capitalising the first letter of each name. There are of course better methods to achieve this use case, however this is just an example of the functionality.

In your DataTableComponent:

1<?php
2 
3namespace App\Livewire;
4 
5use App\Models\User;
6use Rappasoft\LaravelLivewireTables\DataTableComponent;
7use Rappasoft\LaravelLivewireTables\Views\Column;
8 
9class UserTable extends DataTableComponent
10{
11 protected $model = User::class;
12 
13 public function configure(): void
14 {
15 $this->setPrimaryKey('id')
16 ->setDefaultSort('id', 'asc')
17 ->setAdditionalSelects(['users.forename as forename', 'users.surname as surname']);
18 }
19 
20 public function columns(): array
21 {
22 return [
23 Column::make('id', 'id')
24 ->sortable()
25 ->searchable(),
26 Column::make('Email', 'email')
27 ->sortable()
28 ->searchable(),
29 Column::make('Full Name')
30 ->label(fn ($row, Column $column) => ucwords($row->forename ?? '' . ' ' . $row->surname)),
31 
32 ];
33 }
34}

Example Action Column Using Views

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

In your DataTableComponent:

1<?php
2 
3namespace App\Livewire;
4 
5use App\Models\User;
6use Rappasoft\LaravelLivewireTables\DataTableComponent;
7use Rappasoft\LaravelLivewireTables\Views\Column;
8 
9class UserTable extends DataTableComponent
10{
11 protected $model = User::class;
12 
13 public function configure(): void
14 {
15 $this->setPrimaryKey('id');
16 $this->setDefaultSort('id', 'asc');
17 }
18 
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(),
37 
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 }
50}

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:

1Column::make('Action')
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:

1<div>
2 @isset ( $viewLink )
3 <a href="{{ $viewLink }}"><i class="fa-solid fa-eye me-2"></i></a>
4 @endif
5 
6 @isset ( $editLink )
7 <a href="{{ $editLink }}"><i class="fa-solid fa-pen-to-square me-2"></i></a>
8 @endif
9 
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
25</div>

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>

Screenshot

The final result can look something like this:

users-table-action-column