Skip to content

Conversation

@gmazzamuto
Copy link
Contributor

Support :readonly option for all fields.

The :readonly field option, being shared among all fields, has been moved to the @config_schema of Backpex.Field. This should not be a breaking change.

Example of readonly fields:

Screenshot 2025-11-25 at 01-24-43 Edit User · Backpex

@Flo0807 Flo0807 added the enhancement Changes that are not breaking label Nov 28, 2025
</.dropdown>
"""
attr :id, :string, required: true, doc: "unique identifier for the dropdown"
attr :readonly, :boolean, default: false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
attr :readonly, :boolean, default: false
attr :readonly, :boolean, default: false, doc: "whether the dropdown is readonly"

Comment on lines 50 to 55
assigns =
if Map.has_key?(assigns.rest, :disabled) do
assigns
else
put_in(assigns, [:rest, :disabled], Map.get(assigns.rest, :readonly) || false)
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assigns =
if Map.has_key?(assigns.rest, :disabled) do
assigns
else
put_in(assigns, [:rest, :disabled], Map.get(assigns.rest, :readonly) || false)
end

Why do we want to set disabled based on the readonly attribute? If you want to set the input to disabled, you should explicitly pass the disabled attribute, in my opinion.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://github.com/naymspace/backpex/blob/0.16.3/lib/backpex/fields/text.ex#L58

I noticed that we do not set dsiabled in every field (e.g. Backpex.Fields.Select)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah you're right, I'll review your comments to this PR asap (some time has passed and I can't remember right now). Anyways I was confused by the fact that in Backpex almost all fields have

<BackpexForm.input
  ...
  readonly={@readonly}
  disabled={@readonly}
>

Do you think it makes sense to have two separate options, :readonly and :disabled? After all, they serve different purposes. If that's the case I can work on that and add the :disabled option to Backpex.Field.

Comment on lines 215 to 220
assigns =
if Map.has_key?(assigns.rest, :disabled) do
assigns
else
put_in(assigns, [:rest, :disabled], Map.get(assigns.rest, :readonly) || false)
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +68 to +80
trigger_class = (assigns.trigger && assigns.trigger[:class]) || ""

trigger_class =
if assigns.readonly do
["cursor-not-allowed bg-base-200"] ++
(trigger_class
|> Enum.join(" ")
|> String.split()
|> List.delete("bg-transparent")
|> List.delete("input"))
else
trigger_class
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks complicated. Can't we just add additional classes in the markup in case the dropdown is readonly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is why. This is how the dropdown is rendered with the code above:

Screenshot_20251223_173629

Whereas this code:

    trigger_class =
      if assigns.readonly do
        ["cursor-not-allowed bg-base-200"] ++ trigger_class
      else
        trigger_class
      end

results in this, and the field can be even highlighted on mouse click (although the dropdown does not open):

Screenshot_20251223_173556

</:label>
<Form.multi_select
field={@form[@name]}
readonly={@readonly}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undefined attribute "readonly" for component Backpex.HTML.Form.multi_select/1

@doc type: :component

attr :prompt, :string, required: true, doc: "string that will be shown when no option is selected"
attr :readonly, :boolean, default: false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
attr :readonly, :boolean, default: false
attr :readonly, :boolean, default: false, doc: "whether the dropdown is readonly"

Comment on lines 179 to 185
assigns =
if assigns[:readonly] == true do
assigns
else
assign(assigns, :readonly, Backpex.Field.readonly?(field_options, assigns))
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For which cases do we need this?

And can we simplify the if-condition?

Suggested change
assigns =
if assigns[:readonly] == true do
assigns
else
assign(assigns, :readonly, Backpex.Field.readonly?(field_options, assigns))
end
assigns =
if assigns[:readonly] do
assigns
else
assign(assigns, :readonly, Backpex.Field.readonly?(field_options, assigns))
end

Copy link
Contributor Author

@gmazzamuto gmazzamuto Dec 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, the if condition can be simplified.

The reason for this code is because the :readonly assign is not always defined when calling the callback Backpex.Field.render_form/1 and also to allow individual fields in Backpex.Fields.InlineCRUD to be set readonly when the parent InlineCRUD field is not readonly. I will add a comment in the code to clarify this.

The `:readonly` field option, being shared among all fields, has been
moved to the `@config_schema` of `Backpex.Field`.
@gmazzamuto gmazzamuto force-pushed the feature/readonly-fields branch from 30ef1e3 to c2ab647 Compare December 23, 2025 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Changes that are not breaking

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants