Filament: Select Options Grouped by Relationship

Free Snippet

Filament allows us to create Select fields quickly, but they can be hard to read or find specific information. Especially if your records are grouped by a relationship. This example will show how to quickly group your Select options by a Relationship (or anything else).

FilamentExamples ThumbBase (9)

How it works

In filament, you can group your Select options by using a multi-dimensional array like this:

Forms\Components\Select::make('customer_id')
->options([
'Group 1' => [
'Option 1' => 'option-1',
'Option 2' => 'option-2',
],
'Group 2' => [
'Option 3' => 'option-3',
'Option 4' => 'option-4',
],
]),

This will render a select field with two groups containing two options. But what if you want to group your options by a model relationship? You can do that by passing a closure as the first argument of the options method:

Forms\Components\Select::make('customer_id')
->options(function () {
$options = [];
 
$stages = PipelineStage::with(['customers'])->get();
foreach ($stages as $stage) {
$options[$stage->name] = collect($stage->customers)->mapWithKeys(function ($customer) {
return [$customer->id => $customer->first_name . ' ' . $customer->last_name];
})->toArray();
}
 
return $options;
})

In this case, the options allows us to pass a Closure to it. In that closure, we can fetch the required data and return it in the format that the options method expects. In this case, we are fetching all the PipelineStage models with their customers relationships and grouping the customers by stage name. The options method expects an array where the keys are the group names and the values are the options. In this case, the group names are the stage names, and the options are the customers' names.


This example is based on our Customer Management CRM

A few of our Premium Examples: