Skip to content

Commit

Permalink
Clean up forms V1 error trapping
Browse files Browse the repository at this point in the history
  • Loading branch information
mitkins committed Dec 10, 2024
1 parent b401be6 commit 3c6c2b4
Showing 1 changed file with 79 additions and 58 deletions.
137 changes: 79 additions & 58 deletions lib/petal_components/form.ex
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def text_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.text_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -257,7 +258,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def email_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.email_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -271,7 +273,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def number_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.number_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -285,7 +288,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def password_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.password_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -299,7 +303,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def search_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.search_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -313,7 +318,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def telephone_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.telephone_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -327,7 +333,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def url_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.url_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -341,7 +348,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def time_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.time_input(@form, @field, [class: @classes, bob: "yo"] ++ Map.to_list(@rest))}
Expand All @@ -355,7 +363,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def time_select(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
<div class="pc-time-select">
Expand All @@ -371,7 +380,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def datetime_local_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.datetime_local_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -385,7 +395,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def datetime_select(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
<div class="pc-datetime-select">
Expand All @@ -401,7 +412,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def date_select(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
<div class="pc-date-select">
Expand All @@ -417,7 +429,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def date_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.date_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -431,7 +444,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def color_input(assigns) do
assigns = assign_defaults(assigns, color_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, color_input_classes(errors))

~H"""
{Form.color_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -445,7 +459,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def file_input(assigns) do
assigns = assign_defaults(assigns, file_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, file_input_classes(errors))

~H"""
{Form.file_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -459,7 +474,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def range_input(assigns) do
assigns = assign_defaults(assigns, range_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, range_input_classes(errors))

~H"""
{Form.range_input(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -473,7 +489,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def textarea(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.textarea(@form, @field, [class: @classes, rows: "4"] ++ Map.to_list(@rest))}
Expand All @@ -488,7 +505,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def select(assigns) do
assigns = assign_defaults(assigns, select_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, select_classes(errors))

~H"""
{Form.select(@form, @field, @options, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -505,7 +523,8 @@ defmodule PetalComponents.Form do
)

def checkbox(assigns) do
assigns = assign_defaults(assigns, checkbox_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, checkbox_classes(errors))

~H"""
{Form.checkbox(@form, @field, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -522,9 +541,11 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def checkbox_group(assigns) do
errors = used_input_errors(assigns)

assigns =
assigns
|> assign_defaults(checkbox_classes(field_has_errors?(assigns)))
|> assign_defaults(checkbox_classes(errors))
|> assign_new(:checked, fn ->
values =
case Phoenix.HTML.Form.input_value(assigns[:form], assigns[:field]) do
Expand Down Expand Up @@ -576,7 +597,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @checkbox_form_attrs)

def switch(assigns) do
assigns = assign_defaults(assigns, switch_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, switch_classes(errors))

~H"""
<label class={["pc-switch", "pc-switch--#{@size}"]}>
Expand All @@ -587,8 +609,8 @@ defmodule PetalComponents.Form do
"""
end

defp switch_classes(has_errors) do
"#{if has_errors, do: "has-error", else: ""} sr-only peer"
defp switch_classes(errors) do
"#{if errors != [], do: "has-error", else: ""} sr-only peer"
end

attr(:form, :any, default: nil, doc: "")
Expand All @@ -599,7 +621,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def radio(assigns) do
assigns = assign_defaults(assigns, radio_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, radio_classes(errors))

~H"""
{Form.radio_button(@form, @field, @value, [class: @classes] ++ Map.to_list(@rest))}
Expand All @@ -615,9 +638,11 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def radio_group(assigns) do
errors = used_input_errors(assigns)

assigns =
assigns
|> assign_defaults(radio_classes(field_has_errors?(assigns)))
|> assign_defaults(radio_classes(errors))

~H"""
<div class={radio_group_layout_classes(%{layout: @layout})}>
Expand All @@ -636,7 +661,8 @@ defmodule PetalComponents.Form do
attr(:rest, :global, include: @form_attrs)

def hidden_input(assigns) do
assigns = assign_defaults(assigns, text_input_classes(field_has_errors?(assigns)))
errors = used_input_errors(assigns)
assigns = assign_defaults(assigns, text_input_classes(errors))

~H"""
{Form.hidden_input(@form, @field, Map.to_list(@rest))}
Expand All @@ -650,18 +676,14 @@ defmodule PetalComponents.Form do
def form_field_error(assigns) do
assigns =
assigns
|> assign(:translated_errors, generated_translated_errors(assigns.form, assigns.field))
|> assign(:translated_errors, generated_translated_errors(assigns))

~H"""
<%= if field_has_errors?(assigns) and used_input?(@form[@field]) do %>
<div class={@class}>
<%= for translated_error <- @translated_errors do %>
<div class="pc-form-field-error invalid-feedback">
{translated_error}
</div>
<% end %>
<div :if={@translated_errors != []} class={@class}>
<div :for={translated_error <- @translated_errors} class="pc-form-field-error invalid-feedback">
{translated_error}
</div>
<% end %>
</div>
"""
end

Expand All @@ -678,10 +700,10 @@ defmodule PetalComponents.Form do
"""
end

defp generated_translated_errors(form, field) do
defp generated_translated_errors(assigns) do
translate_error = translator_from_config() || (&translate_error/1)

Keyword.get_values(form.errors || [], field)
used_input_errors(assigns)
|> Enum.map(fn error ->
translate_error.(error)
end)
Expand Down Expand Up @@ -731,38 +753,40 @@ defmodule PetalComponents.Form do
end

defp label_classes(assigns) do
errors = used_input_errors(assigns)

type_classes =
if Enum.member?(["checkbox", "radio"], assigns[:type]) do
"pc-label--for-checkbox"
else
""
end

"#{if field_has_errors?(assigns), do: "has-error", else: ""} #{type_classes} #{assigns[:class] || ""} pc-label"
"#{if errors != [], do: "has-error", else: ""} #{type_classes} #{assigns[:class] || ""} pc-label"
end

defp text_input_classes(has_error) do
"#{if has_error, do: "has-error", else: ""} pc-text-input"
defp text_input_classes(errors) do
"#{if errors != [], do: "has-error", else: ""} pc-text-input"
end

defp select_classes(has_error) do
"#{if has_error, do: "has-error", else: ""} pc-select"
defp select_classes(errors) do
"#{if errors != [], do: "has-error", else: ""} pc-select"
end

defp file_input_classes(has_error) do
"#{if has_error, do: "has-error", else: ""} pc-file-input"
defp file_input_classes(errors) do
"#{if errors != [], do: "has-error", else: ""} pc-file-input"
end

defp color_input_classes(has_error) do
"#{if has_error, do: "has-error", else: ""} pc-color-input"
defp color_input_classes(errors) do
"#{if errors != [], do: "has-error", else: ""} pc-color-input"
end

defp range_input_classes(has_error) do
"#{if has_error, do: "has-error", else: ""} pc-range-input"
defp range_input_classes(errors) do
"#{if errors != [], do: "has-error", else: ""} pc-range-input"
end

defp checkbox_classes(has_error) do
"#{if has_error, do: "has-error", else: ""} pc-checkbox"
defp checkbox_classes(errors) do
"#{if errors != [], do: "has-error", else: ""} pc-checkbox"
end

defp checkbox_group_layout_classes(assigns) do
Expand Down Expand Up @@ -805,16 +829,13 @@ defmodule PetalComponents.Form do
end
end

defp radio_classes(has_error) do
"#{if has_error, do: "has-error", else: ""} pc-radio"
defp radio_classes(errors) do
"#{if errors != [], do: "has-error", else: ""} pc-radio"
end

defp field_has_errors?(%{form: form, field: field}) when is_map(form) do
case Keyword.get_values(form.errors || [], field) do
[] -> false
_ -> used_input?(form[field])
end
defp used_input_errors(%{form: form, field: field}) when not is_nil(form) do
if used_input?(form[field]), do: form[field].errors, else: []
end

defp field_has_errors?(_), do: false
defp used_input_errors(_), do: []
end

0 comments on commit 3c6c2b4

Please sign in to comment.