Table Classes
Every table extends Forjed\InertiaTable\Table and implements one required method: columns().
Creating a Table
use Forjed\InertiaTable\Table;
use Forjed\InertiaTable\Column;
class ServerTable extends Table
{
protected function columns(): array
{
return [
Column::make('name', 'Name')->sortable()->text(),
Column::make('ip', 'IP Address')->sortable(),
Column::data('id'),
];
}
}Properties
| Property | Type | Default | Description |
|---|---|---|---|
$defaultSort | string | '-created_at' | Default sort column. Prefix with - for descending |
$perPage | int | 10 (from config) | Rows per page |
$identifier | ?string | null | Scopes all URL params (search, sort, page) - see Identifier |
$tableSettings | array | [] | Extension metadata for the frontend |
Instantiation
The constructor accepts Eloquent\Builder, Query\Builder, or Relation instances:
// Static factory (recommended)
ServerTable::make(Server::query());
// With scopes
ServerTable::make(Server::where('active', true));
// With relations
ServerTable::make($project->servers());Fluent Setters
ServerTable::make(Server::query())
->perPage(25)
->identifier('servers') // scopes URL params for multi-table pages
->withSettings(['key' => 'value']) // extension metadata
->paginate();Identifier
When you have multiple tables on the same page, use identifier() to scope each table's URL parameters. Without an identifier, tables share search, sort, and page params - causing conflicts.
// Table 1 - uses ?serversSearch=, ?serversSort=, ?serversPage=
ServerTable::make(Server::query())
->identifier('servers')
->paginate();
// Table 2 - uses ?sitesSearch=, ?sitesSort=, ?sitesPage=
SiteTable::make(Site::query())
->identifier('sites')
->paginate();| Identifier | Search param | Sort param | Page param |
|---|---|---|---|
null (default) | search | sort | page |
'servers' | serversSearch | serversSort | serversPage |
'sites' | sitesSearch | sitesSort | sitesPage |
You can also set it as a class property:
class ServerTable extends Table
{
protected ?string $identifier = 'servers';
}The identifier is passed to the frontend automatically - no additional React/Vue configuration needed.
Output Methods
For Inertia (paginated response)
| Method | Description |
|---|---|
->paginate() | Full pagination - includes total count and last_page |
->simplePaginate() | Simple pagination - no COUNT(*) query, faster |
// In your controller
return Inertia::render('Servers', [
'servers' => ServerTable::make(Server::query())->paginate(),
]);For raw data (no pagination)
| Method | Description |
|---|---|
->toArray() | All matching rows as a flat array |
->toCollection() | All matching rows as a Laravel Collection |
Both apply search and sorting but skip pagination. Optional take and skip parameters for chunking:
// All rows
$rows = ServerTable::make(Server::query())->toArray();
// As a Collection
$rows = ServerTable::make(Server::query())->toCollection();
// With take/skip
$chunk = ServerTable::make(Server::query())->toArray(take: 100, skip: 200);Response Shape
paginate() and simplePaginate() return an array with these keys:
| Key | Type | Description |
|---|---|---|
columns | array | Column definitions for the frontend |
data | array | Row data (including hidden columns) |
links | array | Pagination URLs (first, last, prev, next) |
meta | array | Pagination metadata (current_page, from, to, per_page, etc.) |
searchable | bool | Whether the table has searchable fields |
searchDebounce | int | Debounce time in ms (from config) |
dateFormat | string | PHP date format string (from config) - used for server-side formatting |
identifier | string|null | Table identifier for scoped URL params |
tableSettings | array | Extension metadata for the frontend |
Default Query Modifications
Override query() to apply default query modifications - eager loading, scopes, joins, or anything else - without touching the constructor:
class ServerTable extends Table
{
protected function query(): void
{
$this->query->with(['owner', 'tags']);
$this->query->where('archived', false);
}
}The query() method runs at the start of every query, before columns are resolved, hooks are executed, and search/sorting are applied:
1. query() <-- your default modifications
2. $columns = $this->columns()
3. Global beforeQuery hooks
4. Class-specific beforeQuery hooks
5. applySearch()
6. applySorting($columns)
7. ...This is different from Table Hooks, which modify tables from the outside (service providers, packages). The query() method is for modifications that are intrinsic to the table class itself.
Searchable Fields
Override searchable() to enable global search:
protected function searchable(): array
{
return ['name', 'ip', 'hostname'];
}Return [] (the default) to disable search.