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

LawrenceSmith's avatar

Table column ordering

Hi

I have a view in MySQL that has numbers and letters and numbers i.e 1, 2 , 3, C1, C2, 10, 20, C29.

The view sorts the column properly as in 1 ..10 and then C1 ... C20 but when I use it as a model in Filament it loses the ordering completely and even the numbers go 1 up to 19 and then carries on with 2, 21 etc.

How can I preserve the ordering I have in the view in the Filament table?

Thanks

0 likes
4 replies
LaryAI's avatar
Level 58

To address the issue of preserving the custom ordering of your column in Filament, you need to ensure that the sorting logic is correctly applied both in your MySQL view and in the Filament model. Here’s a step-by-step solution:

  1. Custom Sorting in MySQL View: Ensure that your MySQL view sorts the column in the desired order. You can use a combination of ORDER BY and custom sorting logic to achieve this. For example:

    CREATE VIEW sorted_view AS
    SELECT *
    FROM your_table
    ORDER BY
      CASE
        WHEN column REGEXP '^[0-9]+$' THEN LPAD(column, 10, '0')
        WHEN column REGEXP '^C[0-9]+$' THEN LPAD(SUBSTRING(column, 2), 10, '0')
      END;
    

    This SQL snippet ensures that numeric values are zero-padded to maintain proper order and that values starting with 'C' are also sorted correctly.

  2. Custom Sorting in Filament: In your Filament model, you need to ensure that the custom sorting logic is applied when fetching data. You can achieve this by overriding the default query used by Filament. Here’s an example in a Filament resource:

    namespace App\Filament\Resources;
    
    use Filament\Resources\Resource;
    use Filament\Resources\Table;
    use Filament\Tables;
    use App\Models\YourModel;
    
    class YourModelResource extends Resource
    {
        protected static string $model = YourModel::class;
    
        public static function table(Table $table): Table
        {
            return $table
                ->columns([
                    Tables\Columns\TextColumn::make('column_name')
                        ->label('Column Name'),
                    // Add other columns as needed
                ])
                ->defaultSort('column_name', 'asc')
                ->query(function ($query) {
                    $query->orderByRaw("
                        CASE
                            WHEN column_name REGEXP '^[0-9]+$' THEN LPAD(column_name, 10, '0')
                            WHEN column_name REGEXP '^C[0-9]+$' THEN LPAD(SUBSTRING(column_name, 2), 10, '0')
                        END
                    ");
                });
        }
    }
    

    In this example, the orderByRaw method is used to apply the same custom sorting logic as in the MySQL view.

By ensuring that both your MySQL view and Filament model apply the same sorting logic, you can preserve the desired order of your column when displaying it in Filament.

If you have any further questions or need additional assistance, feel free to ask!

vincent15000's avatar

I don't know about Filament, but you need to sort by natural order like in the example below.

$ports = Port::
    ->orderByRaw('natural_sort_key(ports.name)')
    ->get();

And it's also possible on a database view ;).

billmn's avatar

In Filament you can use something like this on table column:

TextColumn::make('code')
    ->sortable(query: fn ($query, $direction) =>
        $query->orderByRaw(“NATURAL_SORT_KEY(code) {$direction}”)
    ),

I would recommend to create a query scope in the model with the code above (you could call it scopeOrderNaturalBy) and then use it on the table column and, maybe, in the defaultSort method.

1 like
LawrenceSmith's avatar

Thanks for the advice guys. Let’s see how this goes 😊

1 like

Please or to participate in this conversation.