Black Friday: coupon FRIDAY24 for 40% off Yearly/Lifetime membership! Read more here

Select Options Grouped by Relationship

2024-05-16

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).

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: