Phoenix의 폼 입력을 통하는 헤르파로 사용하기
2021/3/12(金)〜 2021/3/15(月)開催のautoracex #16 での成果입니다.
TL;DR
元ネタは José Valimさん の Dynamic forms with Phoenix ですが、それをもとに必須項目の印を表示させたり、 Bootstrap 4 に対応させたりしました.これは一例です.ひとそれぞれ好きなようにElixirで카스타마이즈데키마스.
以下のようなのフォームがあったとして
카스탐
input_tag
헤르파를 사용하는 라벨, 스타일링, 에라멧세이지를 を含んだHTML을 움직이는 に生成させます.<%= f = form_for @changeset, "#", phx_submit: "submit-check-in-form" %>
<%= input_tag f, :name %>
<%= input_tag f, :phone %>
<%= submit "Check In", phx_disable_with: "Saving ...", class: "btn btn-primary" %>
</form>
未提出、提出後GOOD、提出後BAD의 3파탄の状態が考えられます.formの状態に対応したCSScrasto共にHTMLが生成されます.
formtype은, フィールド名から推測して生成します.데포르트はPhoenix.HTML.Form.text_input/3
입니다.
피르드명
HTML 생성에 사용하는 방법
:email
Phoenix.HTML.Form.email_input/3:password
Phoenix.HTML.Form.password_input/3:search
Phoenix.HTML.Form.search_input/3:url
Phoenix.HTML.Form.url_input/3<!-- 提出前 -->
<div class="form-group">
<label for="volunteer_name">Name *</label>
<input type="text"
class="form-control "
id="volunteer_name"
name="volunteer[name]"
placeholder="Name">
</div>
<!-- 提出後BAD -->
<div class="form-group">
<label for="volunteer_name">Name *</label>
<input type="text"
class="form-control is-invalid" <-- CSSが変化
id="volunteer_name"
name="volunteer[name]"
placeholder="Name"
value="">
<span class="invalid-feedback d-inline-block"
phx-feedback-for="volunteer_name">
can't be blank
</span>
</div>
<!-- 提出後GOOD -->
<div class="form-group">
<label for="volunteer_name">Name *</label>
<input type="text"
class="form-control is-valid" <-- CSSが変化
id="volunteer_name"
name="volunteer[name]"
placeholder="Name"
value="Masatoshi">
</div>
카스탐 input_tag 헤르파実装예
defmodule MnishiguchiWeb.InputHelpers do
use Phoenix.HTML
@custom_field_form_mapping %{
"phone" => :telephone_input
}
@doc """
Dynamically generates a Bootstrap 4 form input field.
http://blog.plataformatec.com.br/2016/09/dynamic-forms-with-phoenix/
## Examples
input_tag f, :name, placeholder: "Name", autocomplete: "off"
input_tag f, :phone, using: :telephone_input, placeholder: "Phone", autocomplete: "off"
"""
def input_tag(form, field, opts \\ []) do
# Some input type can be inferred from the field name.
input_fun_name = opts[:using] || Phoenix.HTML.Form.input_type(form, field, @custom_field_form_mapping)
required = opts[:required] || form |> input_validations(field) |> Keyword.get(:required)
label_text = opts[:label] || humanize(field)
permitted_input_opts = Enum.filter(opts, &(elem(&1, 0) in [:id, :name, :autocomplete, :placeholder]))
phx_attributes = Enum.filter(opts, &String.starts_with?(to_string(elem(&1, 0)), "phx_"))
custom_class = [class: "form-control #{form_state_class(form, field)}"]
input_opts =
(permitted_input_opts ++ phx_attributes ++ custom_class)
|> Enum.reject(&is_nil(elem(&1, 1)))
content_tag :div, class: "form-group" do
label = label_tag(form, field, label_text, required)
input = apply(Phoenix.HTML.Form, input_fun_name, [form, field, input_opts])
error = MnishiguchiWeb.ErrorHelpers.error_tag(form, field)
[label, input, error]
end
end
defp form_state_class(form, field) do
cond do
# Some forms may not use a Map as a source. E.g., :user
!is_map(form.source) -> ""
# Ignore Conn-based form.
Map.get(form.source, :__struct__) == Plug.Conn -> ""
# The form is not yet submitted.
!Map.get(form.source, :action) -> ""
# This field has an error.
form.errors[field] -> "is-invalid"
true -> "is-valid"
end
end
end
입력 유형
Phoenix.HTML.Form.input_type/3 により 、 、 입력 項目 項目 名 を もと もと に に に に の の 決定 決定 し ます ます. 仕組 み は シンプル です.. 予め 用意 用意 さ さ れ た マッピング が 使用 使用 さ れ. デフォルト の マッピング は は 下記 の の です です.. 第 3 3 引数 し し し し し し し し し し し の の の の の マッピング マッピング マッピング マッピング マッピング マッピング マッピング マッピング マッピング し し し し し し し し し し し し マッピング マッピング マッピング マッピング マッピング マッピング マッピング は 下記 の の です です です. ∎ていするとデフォルトのマッpingにマージされます.
%{"email" => :email_input,
"password" => :password_input,
"search" => :search_input,
"url" => :url_input}
:xxx_input
アトムは Phoenix.HTML.Form に予め用意された関数名와 一致している必要があります.理解を深めるために、Iexで挙動を確認してみます.例では、
volunteers
テーブルと Volunteer
skiーmaがあることを想定しています.iex> alias Mnishiguchi.Volunteers.Volunteer
iex> import Ecto.Changeset
iex> changeset = %Volunteer{} |> cast(%{}, [:name]) |> validate_required([:name])
#Ecto.Changeset<
action: nil,
changes: %{},
errors: [
name: {"can't be blank", [validation: :required]},
],
data: #Mnishiguchi.Volunteers.Volunteer<>,
valid?: false
>
iex> form = Phoenix.HTML.Form.form_for changeset, "#"
%Phoenix.HTML.Form{
action: "#",
data: %Mnishiguchi.Volunteers.Volunteer{
__meta__: #Ecto.Schema.Metadata<:built, "volunteers">,
id: nil,
inserted_at: nil,
name: nil,
updated_at: nil
},
errors: [],
hidden: [],
id: "volunteer",
impl: Phoenix.HTML.FormData.Ecto.Changeset,
index: nil,
name: "volunteer",
options: [method: "post"],
params: %{},
source: #Ecto.Changeset<
action: nil,
changes: %{},
errors: [
name: {"can't be blank", [validation: :required]},
],
data: #Mnishiguchi.Volunteers.Volunteer<>,
valid?: false
>
}
# using default mapping
iex> Phoenix.HTML.Form.input_type(form, :name)
:text_input
iex> Phoenix.HTML.Form.input_type(form, :email)
:email_input
iex> Phoenix.HTML.Form.input_type(form, :search)
:search_input
iex> Phoenix.HTML.Form.input_type(form, :password)
:password_input
iex> Phoenix.HTML.Form.input_type(form, :url)
:url_input
# 第3引数にカスタムマッピングを指定するとデフォルトにマージされます。
iex> Phoenix.HTML.Form.input_type(form, :denwa, %{"denwa" => :telephone_input})
:telephone_input
必須項目かどうか
必須項目かどうかは Phoenix.HTML.Form.input_validations/2 で確認できます.
iex> form |> input_validations(:name)
[required: true]
iex> form |> input_validations(:name) |> Keyword.get(:required)
true
iex> form |> input_validations(:hello) |> Keyword.get(:required)
false
HTMLをElixir로 끝내기
Phoenix.HTML.Tag.content_tag/2 を用い、ElixirでHTMLを組み立てることができます.他にも同様の関数が Phoenix.HTML.Form functions に用意されてます.
iex> Phoenix.HTML.Tag.content_tag(:p, "hello")
{:safe, [60, "p", [], 62, "hello", 60, 47, "p", 62]}
iex> Phoenix.HTML.Tag.content_tag(:p, "hello") |> Phoenix.HTML.safe_to_string
"<p>hello</p>"
인간화하다
Phoenix.HTML.Form.humanize/1 が便利입니다.
iex> Phoenix.HTML.Form.humanize("name")
"Name"
iex> Phoenix.HTML.Form.humanize("hello_world")
"Hello world"
資料
Dynamic forms with Phoenix by José Valimさん
Reference
이 문제에 관하여(Phoenix의 폼 입력을 통하는 헤르파로 사용하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mnishiguchi/phoenix-input-n99텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)