Havit.Blazor
Havit.Blazor copied to clipboard
Enable HxFormState to force disable form elements
Problem
HxFormState
is a cascading parameter that affects the enabled or disabled state of form elements. However, it only applies if Enabled
attribute is not set on the individual element. The current logic for determining the effective state of an element is (CascadeEnabledComponent.EnabledEffective):
return component.Enabled ?? component.FormState?.Enabled ?? true;
This means that HxFormState
can only disable an element if it is not explicitly enabled.
Scenario
I have a situation where the state of the elements depends on both business logic and security settings. I want to be able to disable all the elements based on security settings, regardless of the business logic. The current solution requires me to write something like this:
Enabled="IsEnabled && (FormState?.Enabled ?? false)"
This is cumbersome and error-prone.
Solution
I suggest adding a parameter called e.g. ForceDisabled
to HxFormState
and a corresponding property to the FormState
class. This parameter would allow HxFormState
to force disable any form element, regardless of its own Enabled
attribute. The logic for determining the effective state of an element would change to:
return component.FormState?.ForceDisabled ?? false ? false : component.Enabled ?? component.FormState?.Enabled ?? true;
This way, I can use HxFormState
to force disable any form element. For example:
<HxFormState ForceDisabled="!IsAuthorized">
<!-- form elements here -->
</HxFormState>
Notes
- There might be cases where some elements need to be enabled even when everything else is disabled (e.g. a cancel button). This can be achieved by nesting HxFormState components with different values of ForceDisabled.
- There might also be a need for a ForceEnabled parameter, but I don't have a use case for it right now.
- A solution of problem can also be to have business logic enabled
null
/false
insteadtrue
/false
but it does not look well.
I understand the scenario you are facing and the need for some elegant solution.
On the other hand, I do not find the <HxFormState ForceDisabled="true"
>` elegant enough. ;-)
We will discuss this on our library design meeting, but some enum might work.
💡...or we can just change the specification in a way where disabled state always precedes enabled state (i.e. you cannot override <HxFormState Enabled="false" />
with <HxComponent Enabled="true" />
)? Is there any scenario where you would want to override higher-level disabled with lower-level enabled? (Might be achieved with HxFormState nesting for those rare cases?)
I was expecting that <HxFormState Enabled="false" />
would disable all the components and I was surprised by the current behavior. I think that having some enabled elements in a disabled form is a rare case (for example, a cancel button). However, I think that changing the specification might be too disruptive for some users.
An attribute that specifies the mode of disabling, so that users can choose whether they want to override the higher-level disabled state with lower-level enabled state or not, would be convenient as well.
@jirikanda Your opinion? @crdo?
Is there any scenario where you would want to override higher-level disabled with lower-level enabled?
Yes, I use this approach to enable buttons for downloading attachments / generating pdf documents for a completely disabled (because it is in "readonly" state) entity.