ENUM fields with forms Select inputs
Describe the bug
When you have a proper casting set up in the model with an ENUM field, form fields may experience issues with rendering such fields, even when you pass $options as an array.
For example:
File: resources / views / vendor / platform / fields / select.blade.php : 14
Error: Cannot use object of type App\Enums\EnumType as array
To Reproduce Steps to reproduce the behaviour:
- You have a model with an enum field cast, for example something like that:
protected $casts = [
'enabled' => 'boolean',
'type' => EnumType::class,
'provider' => EnumProvider::class,
'rules' => 'array',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
- Plus, you have an
options()method that will return a prepared key-label array for select input. That is a sort of workaround to make "options" for the Select input. For example:
namespace App\Enums;
enum EnumType: string
{
case TEXT = 'text';
case NUMBER = 'number';
case PRICE = 'price';
/**
* Get a label
*/
public function label(): string
{
return match ($this) {
self::TEXT => __('Text'),
self::NUMBER => __('Numeric'),
self::PRICE => __('Price'),
};
}
/**
* Get all available types as an array
*/
public static function options(): array
{
$options = collect(self::cases())
->mapWithKeys(fn($case) => [$case->value => $case->label()])
->toArray();
return $options;
}
- Then you create a select field on the form:
Select::make('enum_type')
->required()
->title('Enum Type')
->empty(__('Select type'))
->options(EnumType::options())
->help(__('Enum typed options list from the model')),
Expected behaviour A select element that will have options pre-selected based on the Enum type of field. P.S. Additionally, the desired behaviour is to pass just the Enum class as options, and it will render options for that.
Server (please complete the following information):
- Platform Version: 14.52
- Laravel Version: 12.18
- PHP Version: 8.4
For now, the solution I came up with is to edit the select template and add Enum type checks for the current option as the $value variable loads as an Enum type. And second addition is to avoid "empty()" param, which adds value with an empty $key to not throw an error as well.
@component($typeForm, get_defined_vars())
<div data-controller="select"
data-select-placeholder="{{$attributes['placeholder'] ?? ''}}"
data-select-allow-empty="{{ $allowEmpty }}"
data-select-message-notfound="{{ __('No results found') }}"
data-select-allow-add="{{ var_export($allowAdd, true) }}"
data-select-message-add="{{ __('Add') }}"
>
<select {{ $attributes }}>
@foreach($options as $key => $option)
<option value="{{$key}}"
@isset($value)
@if (is_array($value) && in_array($key, $value)) selected
@elseif ($value instanceof \UnitEnum && $value->value === $key) selected
@elseif (!($value instanceof \UnitEnum) && isset($value[$key]) && $value[$key] == $option) selected
@elseif ($key == $value) selected
@endif
@endisset
>{{$option}}</option>
@endforeach
</select>
</div>
@endcomponent
I think this can be simplified by using the ->fromEnum() method, which is specifically designed for cases like this.
Here's an example from the Orchid tests: https://github.com/orchidsoftware/platform/blob/ba754210adb0045046769987b78652a23e84a935/tests/Unit/Screen/Fields/SelectTest.php#L271-L280
Interesting, I wasn't aware of that functionality already in place! Is it worth adding to the Example screens or documentation? Correct me if I am wrong, but this seems to be undocumented functionality 🤔 https://orchid.software/en/docs/field/#select
P.S. seem like we can close this as there is a solution for Enums :)
I believe this might be useful to have in the documentation. Would it be possible to add an example?