filamentphp / filament

A collection of beautiful full-stack components for Laravel. The perfect starting point for your next app. Using Livewire, Alpine.js and Tailwind CSS.
https://filamentphp.com
MIT License
18.08k stars 2.83k forks source link

Select doesn't honor `disabled` #8097

Closed vincenzoraco closed 1 year ago

vincenzoraco commented 1 year ago

Package

filament/filament

Package Version

v3.0.34

Laravel Version

v10.20.0

Livewire Version

No response

PHP Version

PHP 8.1.0

Problem description

The Select field is still clickable and a new option can be selected even when conditionally disabled.

This happens only when using ->native(false) - the problem doesn't exist using the native approach.

Forms\Components\Select::make('type_id')
    ->options([
        1 => 'Type 1',
        2 => 'Type 2',
    ])
    ->native(false)
    ->live()
    ->disabled(fn($state): bool => filled($state))

The issue doesn't appear if the field was disabled from the beginning

Forms\Components\Select::make('type_id')
    ->options([
        1 => 'Type 1',
        2 => 'Type 2',
    ])
    ->native(false)
    ->live()
    ->disabled(fn($state) => true)

The field is in a disabled state (from an HTML/CSS point of view), but it allows a selection anyway.

Here's a video to show the behaviour

https://github.com/filamentphp/filament/assets/5623078/a8754196-8a2f-45f5-bbb6-406591b6851b

This issue might be similar or related to https://github.com/filamentphp/filament/issues/7370

Expected behavior

It's implied that the field should not allow a selection if disabled

Steps to reproduce

Create a live form component where the disabled function is dictated dynamically

Forms\Components\Select::make('type_id')
    ->options([
        1 => 'Type 1',
        2 => 'Type 2',
    ])
    ->native(false)
    ->live()
    ->disabled(fn($state): bool => filled($state))

Reproduction repository

https://github.com/vincenzoraco/filament-select-disabled-reproduction-bug

Relevant log output

No response

vincenzoraco commented 1 year ago

I need to also know if this is design choice or a bug

When a field is marked as disabled, it's not passed in protected function mutateFormDataBeforeCreate(array $data): array and neither in protected function handleRecordCreation(array $data): Model

If it should still be passed, I can create a issue with a new repo for this?

sakanjo commented 1 year ago

@vincenzoraco Thanks for reporting the issue, this bug is related to #7370, which only appears to exist when using non-native elements.


I need to also know if this is design choice or a bug

When a field is marked as disabled, it's not ...

This is by design choice, if you want to override the default behavior add dehydrated(fn() => true) after the disabled(...),

But it's a bad idea since the user can manipulate the request payload and set another value from the edit form, to overcome this issue you will need to only call dehydrated on the create form only.

Select::make(...)
  ->disabled(fn ($state): bool => filled($state))
  ->dehydrated(fn () => true)
zepfietje commented 1 year ago

@vincenzoraco Thanks for reporting the issue, this bug is related to #7370, which only appears to exist when using non-native elements.

I don't think it is related, @sakanjo.

This is a known limitation of Choices.js (search through old issues and you'll find a bunch). Nothing we can do here really unless you're able to fix this with a PR to Choices.js. 🙂

neneone commented 12 months ago

Same problem here. @vincenzoraco have you found a solution?