# Components Library This library only comes with building blocks for your components, and you should built your own form components - or use the provided building blocks directly. Feel free to grab and customize these components to your needs, and treat them as a starting point when building your form builder. The code below is released under public domain: defmodule MyAppWeb.FormComponents do use MyAppWeb, :component import Spike.LiveView.Components def errors_component(%{form: _, field: _, errors: _} = assigns) do ~H""" <.errors :let={field_errors} field={@field} form={@form} errors={@errors}> <%= field_errors |> Enum.map(fn {_k, v} -> v end) |> Enum.join(", ") %> """ end def label_component(%{ref: _ref, text: _text, field: _field} = assigns) do assigns = assign_new(assigns, :required, fn -> false end) if assigns.required do ~H""" """ else ~H""" """ end end def input_component(%{type: "textarea", field: _, form: _, errors: _} = assigns) do assigns = assigns |> assign_new(:target, fn -> nil end) ~H"""
<%= if @label do %> <.label_component text={@label} ref={@form.ref} field={@field} required={is_required?(@form, @field)} /> <% end %> <.form_field field={@field} form={@form} target={@target}> <.errors_component form={@form} field={@field} errors={@errors} />
""" end def input_component(%{type: type, field: _, form: _, errors: _} = assigns) when type in ["text", "password", "email"] do assigns = assigns |> assign_new(:target, fn -> nil end) ~H"""
<%= if @label do %> <.label_component text={@label} ref={@form.ref} field={@field} required={is_required?(@form, @field)} /> <% end %> <.form_field field={@field} form={@form} target={@target}> Map.get(@field)} /> <.errors_component form={@form} field={@field} errors={@errors} />
""" end def input_component(%{type: "checkbox", field: _, form: _, errors: _} = assigns) do assigns = assigns |> assign_new(:checked_value, fn -> "1" end) |> assign_new(:unchecked_value, fn -> "0" end) |> assign_new(:target, fn -> nil end) ~H"""
<.form_field field={@field} form={@form} target={@target}> <%= if @label do %> <.label_component text={@label} ref={@form.ref} field={@field} required={is_required?(@form, @field)} /> <% end %> <.errors_component form={@form} field={@field} errors={@errors} />
""" end def input_component(%{type: "select", field: _, form: _, errors: _, options: _} = assigns) do assigns = assigns |> assign_new(:target, fn -> nil end) ~H"""
<%= if @label do %> <.label_component text={@label} ref={@form.ref} field={@field} required={is_required?(@form, @field)} /> <% end %> <.form_field field={@field} form={@form} target={@target}> <.errors_component form={@form} field={@field} errors={@errors} />
""" end def input_component(%{type: "radio", field: _, form: _, errors: _, options: _} = assigns) do assigns = assigns |> assign_new(:target, fn -> nil end) ~H"""
<%= if @label do %> <.label_component text={@label} ref={@form.ref} field={@field} required={is_required?(@form, @field)} /> <% end %> <.form_field field={@field} form={@form} target={@target}> <%= for {{value, text}, index} <- Enum.with_index(@options) do %> Map.get(@field) == value} /> <.label_component text={text} ref={@form.ref} field={"#{@field}_#{index}"} />
<% end %> <.errors_component form={@form} field={@field} errors={@errors} />
""" end defp is_checked?(form, field, checked_value) do Map.get(form, field) == checked_value || Map.get(form, field) == true end defp is_required?(form, field) do validations = Vex.Extract.settings(form) |> Map.get(field, []) {:presence, true} in validations end end Also see [Spike Example app](https://github.com/hubertlepicki/spike_example) for more examples.