Filament Dependent Selects: Auto-Pick the Only Valid Option

2026-04-08 Filament v4/5

You have two dependent selects in a Filament form: Customer and Vehicle. When the user picks a customer, the vehicle dropdown filters down to only that customer's vehicles. But if that customer only has one vehicle, why make the user click the dropdown and select it? You can auto-fill it.

And if the dropdown has more than one value, it's the same old behavior of "Choose an option" as default.

Small UX win that makes your form feel smarter. Let's set it up.


The Typical Setup

Most developers start with something like this:

use Filament\Forms\Components\Select;
 
Select::make('customer_id')
->relationship('customer', 'name');
 
Select::make('vehicle_id')
->options(Vehicle::pluck('model', 'id'));

This doesn't filter vehicles by customer at all. Every vehicle shows up regardless of who's selected. That means users can pick invalid combinations, and you're relying on backend validation to catch it.


The Better Version

We need three things:

  1. Make the customer select live() so it triggers updates on change
  2. Filter the vehicle options based on the selected customer
  3. Auto-select the vehicle when there's only one match

app/Filament/Resources/Orders/Schemas/OrderForm.php

use App\Models\Vehicle;
use Filament\Forms\Components\Select;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Illuminate\Support\Collection;
 
Select::make('customer_id')
->relationship('customer', 'name')
->live()
->afterStateUpdated(function (Set $set, ?int $state) {
$set('vehicle_id', null);
 
if ($state) {
$vehicles = Vehicle::where('customer_id', $state)->get();
 
if ($vehicles->count() === 1) {
$set('vehicle_id', $vehicles->first()->id);
}
}
}),
 
Select::make('vehicle_id')
->options(function (Get $get): Collection {
$customerId = $get('customer_id');
 
if (! $customerId) {
return collect();
}
 
return Vehicle::where('customer_id', $customerId)
->get()
->mapWithKeys(fn (Vehicle $vehicle) => [
$vehicle->id => "{$vehicle->year} {$vehicle->make} {$vehicle->model}",
]);
})
->live(),

How It Works

  1. ->live() on the customer select tells Filament to send a server request whenever the value changes.
  2. afterStateUpdated() fires after that change. First it resets vehicle_id to null, clearing any previously selected vehicle that might now be invalid.
  3. Then it queries vehicles for the new customer. If there's exactly one, it calls $set('vehicle_id', ...) to auto-fill it.
  4. The vehicle select uses a closure for options() that reads the current customer_id via $get() and returns only matching vehicles. This keeps the dropdown in sync even if the user wants to change the auto-selected value.

The reset step is important. Without $set('vehicle_id', null), switching from Customer A to Customer B could leave Customer A's vehicle selected in the field, even though it's no longer in the options list.

A few of our Premium Examples: