Column Sorting & Order Queries
Zonvoir Table supports sorting directly from column headers.
Only columns explicitly marked as sortable can be used to sort the table.
Make a column sortable
Section titled “Make a column sortable”Use sortable() on any column that should support sorting.
use Zonvoir\ZonvoirTable\Columns\TextColumn;
TextColumn::make('name') ->sortable();You can make multiple columns sortable:
public function columns(): array{ return [ TextColumn::make('name') ->sortable(),
TextColumn::make('email') ->sortable(),
DateTimeColumn::make('created_at') ->label('Created') ->sortable(), ];}Users can then sort the table by interacting with the corresponding column headers.
Sort direction
Section titled “Sort direction”Sorting supports both ascending and descending directions.
For example, sorting by name in ascending order:
?sort=nameDescending order is represented by prefixing the column with -:
?sort=-nameThe frontend adapter handles switching between sort directions when the user interacts with a sortable column.
Default sorting
Section titled “Default sorting”Use $defaultSort to define how the table should be sorted when no sort has been selected by the user.
final class UsersTable extends Table{ protected ?string $defaultSort = 'name';}This sorts users by name in ascending order.
Descending by default
Section titled “Descending by default”Prefix the column name with - to use descending order:
final class UsersTable extends Table{ protected ?string $defaultSort = '-created_at';}This is useful for tables where the newest records should appear first.
Custom sorting
Section titled “Custom sorting”For simple columns, Zonvoir Table can apply the sort directly to the underlying query.
Sometimes the displayed column does not map directly to a sortable database column. Use sortUsing() when you need to control how the query is ordered.
TextColumn::make('company.name') ->sortable() ->sortUsing( fn ($query, string $direction) => $query ->orderBy('companies.name', $direction) );The callback receives the table query and the requested sort direction.
ascdescThis gives you full control over the query while keeping the normal sorting experience on the frontend.
Sorting computed values
Section titled “Sorting computed values”sortUsing() is also useful when a displayed value is generated or mapped from other fields.
TextColumn::make('full_name') ->sortable() ->sortUsing( fn ($query, string $direction) => $query ->orderBy('first_name', $direction) ->orderBy('last_name', $direction) );The table can display full_name while the database query determines how that value should actually be sorted.
Sorting and mapAs()
Section titled “Sorting and mapAs()”mapAs() changes the value sent to the frontend, but it does not automatically change how the database query is sorted.
TextColumn::make('name') ->mapAs(fn ($value) => strtoupper($value)) ->sortable();The displayed value may be transformed, while sorting continues to use the underlying name field.
When the displayed value requires different sorting behavior, combine it with sortUsing().
TextColumn::make('company') ->mapAs(fn ($value, User $user) => $user->company->name) ->sortable() ->sortUsing( fn ($query, string $direction) => $query ->orderBy('companies.name', $direction) );URL persistence
Section titled “URL persistence”The active sort is stored in the query string so the current ordering survives navigation and page reloads.
?sort=nameFor descending order:
?sort=-created_atWhen multiple named tables are rendered on the same page, each table keeps its sorting state isolated.
?users[sort]=name&jobs[sort]=-created_atOnly declared sortable columns are accepted as sort keys, preventing arbitrary query parameters from sorting fields that your table has not exposed.