Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jj63systems's avatar

Sort order in a Filament Table after data change

Hi I have a Filament table and in this we're showing columns such as name, description, qty. We also have a ToggleColumn which sets a boolean in the background. This all works well as far as the database side of things is concerned.

We allow the user to column sort on the Qty heading. When the user has this sort option selected and then toggles the boolean the data is refreshed BUT the order changes unpredictably when there are several rows with the same Qty value.

Is it possible to tell Filament to always append as a 2nd sort key the row's ID value such that when sorting on a column that has the same value present on multiple rows, the order is consistent?

thx! j

0 likes
6 replies
LaryAI's avatar
Level 58

To ensure consistent sorting in a Filament table when multiple rows have the same value in a column, you can append a secondary sort key, such as the row's ID. This will help maintain a predictable order even when the primary sort column has duplicate values.

Here's how you can achieve this in a Filament table:

  1. Define the Table Columns: Ensure you have your columns defined, including the ToggleColumn and any other columns you need.

  2. Set Up Sorting: When defining the table, you can specify the default sorting behavior. You can append the ID as a secondary sort key when sorting by the Qty column.

Here's an example of how you might set this up in your Filament table configuration:

use Filament\Tables;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Columns\ToggleColumn;

class YourTable extends Tables\Table
{
    protected function getTableColumns(): array
    {
        return [
            TextColumn::make('name'),
            TextColumn::make('description'),
            TextColumn::make('qty')
                ->sortable(),
            ToggleColumn::make('your_boolean_column'),
        ];
    }

    protected function getTableQuery()
    {
        return YourModel::query()
            ->orderBy('qty')
            ->orderBy('id'); // Append ID as a secondary sort key
    }
}

Explanation:

  • orderBy('qty'): This sets the primary sort key to the qty column.
  • orderBy('id'): This appends the ID as a secondary sort key, ensuring that when multiple rows have the same qty, they are sorted by their ID, maintaining a consistent order.

By implementing this approach, you ensure that the table's sorting behavior remains predictable, even when there are duplicate values in the primary sort column.

jj63systems's avatar

@LaryAI

In the suggested code it's hard-coding the sort order

    protected function getTableQuery()
    {
        return YourModel::query()
            ->orderBy('qty')
            ->orderBy('id'); // Append ID as a secondary sort key
    }

As the user is able to change the sort order what I am seeking is a solution where, irrespective of the column the user selects, the 'id' column is appended as the final sort key

Does that change your response?

Sinnbeck's avatar

Pass in a closure or an array that sorts by the column and then a secondary one. This ensures that it is predictable

https://filamentphp.com/docs/3.x/tables/columns/getting-started#sorting

I would suggest using id as the secondary column.. And this is a known "issue" with sorting in sql. If multiple rows have the same value, there is no guarantee that the order always is the same. Therefor you add a secondary column to make sure it knows how to sort "equal" rows

For instance

 TextColumn::make('qty')
                ->sortable(['qty', 'id']),
jj63systems's avatar

@Sinnbeck

OK got it - thanks. Am well aware of relational database and the impact of not specifying an "order by" on a select statement - unpredictable ordering.

I tried this (the column actually isn't qty but I was just using that as a "for example" and the generated SQL in the laravel.log file is

select * from "arch_folders_v" where ("is_searchable" = ?) and (lower(name::text)::text like ?) order by "id" asc, "num_files_total" asc

The column definition is

                Tables\Columns\TextColumn::make('num_files_total')
                    ->label('Number of files')
                    ->sortable(['num_files_total', 'id'])
                    ->numeric(),

So it appears to be using the two arguments presented to sortable() in the reverse order - is that in fact as it should be (i.e. the opposite order of how you'd code the SQL)? I reversed the args and it now behaves consistently but I'd like to understand if I misinterpreted the solution.

thanks j

Sinnbeck's avatar

@jj63systems Oh didnt know it would swap them. Seems weird. Just swap them in the array and you should be good. The predictable column should come last :)

->sortable(['id', 'num_files_total'])

Please or to participate in this conversation.