Havit.Blazor icon indicating copy to clipboard operation
Havit.Blazor copied to clipboard

Enable HxFormState to force disable form elements

Open TPIvan opened this issue 1 year ago • 4 comments

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 instead true/false but it does not look well.

TPIvan avatar Jul 17 '23 14:07 TPIvan

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?)

hakenr avatar Jul 17 '23 14:07 hakenr

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.

TPIvan avatar Jul 17 '23 15:07 TPIvan

@jirikanda Your opinion? @crdo?

hakenr avatar Jul 18 '23 08:07 hakenr

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.

CryptKat avatar Jul 20 '23 06:07 CryptKat