Sometimes, we have to limit the number of entries we can select. For example, your Employee can only work on one Client at a time.
When dealing with Select fields, we typically pass in a list of options to the options
property like this:
Forms\Components\Select::make('employee_id') ->label('Assigned Employee') ->options(User::pluck('name', 'id'))
And this works perfectly fine. However, sometimes, we need to disable specific options in the list. For example, if the Option has already been selected, we might want to hide it. To do this, we can write a custom Closure that does that:
Forms\Components\Select::make('employee_id') ->label('Assigned Employee') ->options(function ($record) { return User::where('role_id', Role::where('name', 'Employee')->first()->id) ->whereDoesntHave('customers') ->when($record, function ($query, $record) { return $query->orWhere('id', $record->employee_id); }) ->pluck('name', 'id'); })
But hold on, what did we do here? Let's break it down:
options
method.edit
forms where we must include the selected Option.Employee
who don't have any customers assigned to them.when
method to include the selected employee in the list. This is only for edit
forms.name
and id
columns to create the options list.Once this is done, the select field will only show employees with no customers assigned to them.
At the same time, we can simplify this code to it's core:
Forms\Components\Select::make('employee_id') ->label('Assigned Employee') ->options(function ($record) { return User::query() // Here, we are filtering out a specific relationship. ->whereDoesntHave('customers') ->when($record, function ($query, $record) { return $query->orWhere('id', $record->employee_id); }) ->pluck('name', 'id'); })
Of course, we can expand this from here to limit how many times the same Option can be selected. It all depends on your query using the options
method.
This example is based on our Customer Management CRM
A few of our Premium Examples: