엘릭서 피닉스 폼 필드 원 라이너
Necessity is the mother of invention.
フォームのスタイリングを抽象化する方法はいくつかありますが、個人的にフォームフィールドはヘルパー関数を自作するのが一番シンプルな気がしており、実際にやってみた結果も気に入ってます.
やりたいこと
예를 들어,
mix phx.gen.auth
コマンドで生成される以下のようなフォームフィールドがあります.<%= label f, :email %>
<%= email_input f, :email, required: true %>
<%= error_tag f, :email %>
それを このように共通のCSSクラスも含め一行で簡潔に記述したいのです.
<%= bulma_input f, :email %>
動作環境
elixir 1.13.4-otp-24
erlang 24.3.4
❯ mix phx.new --version
Phoenix installer v1.6.8
아이데아
카스탐 뷰헤르파를 기록할 수 있는 방법에 대한 지식과 아이데아는 Elixir言語의 작가 José Valimさんがこの記事( Dynamic forms with Phoenix )の中で丁寧に解説してくれています.
ですのでそれを読めば大体わかります.
また、 Phoenix 자가가
Phoenix.HTML.Form
等 ビルトインのヘルパー関数を多数持っているのでそれらを大いに活用することも大事だと思います.やってみる
lib/my_app_web/views/input_helpers.ex
ファイルを作成.defmodule MyAppWeb.InputHelpers do
use Phoenix.HTML
# TODO: define my custom view helper functions
end
lib/my_app_web.ex
의 view_helpers
関数でそれを忘れずにinportしておく. defp view_helpers do
quote do
# Use all HTML functionality (forms, tags, etc)
use Phoenix.HTML
# Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc)
import Phoenix.LiveView.Helpers
import MyAppWeb.LiveHelpers
# Import basic rendering functionality (render, render_layout, etc)
import Phoenix.View
+ import MyAppWeb.InputHelpers
import MyAppWeb.ErrorHelpers
import MyAppWeb.Gettext
alias MyAppWeb.Router.Helpers, as: Routes
end
end
あとは
MyAppWeb.InputHelpers
に好きなようにヘルパー関数を定義するだけ.先日たまたま Bulma CSS 플레임워크를 사용하기 위해 시간에, 사용하기 위해 한 가지 작업을 하기 위해 사용했습니다.
一つの三プルコードになるかもしれません.
defmodule MyAppWeb.InputHelpers do
use Phoenix.HTML
def bulma_input(form, field, opts \\ []) do
label_opts = Keyword.take(opts, ~w[required label]a)
input_opts = Keyword.drop(opts, ~w[required label]a)
content_tag :div, class: "field" do
[
build_label(form, field, label_opts),
build_input(form, field, input_opts),
MyAppWeb.ErrorHelpers.error_tag(form, field)
]
end
end
def bulma_checkbox(form, field, opts \\ []) do
content_tag :label, class: "checkbox" do
[
checkbox(form, field, opts),
' ',
opts[:label] || field |> to_string() |> Phoenix.Naming.humanize()
]
end
end
defp build_label(form, field, opts) do
required = opts[:required] || Keyword.get(input_validations(form, field), :required)
label_text = (opts[:label] || humanize(field)) <> if required, do: " *", else: ""
Phoenix.HTML.Form.label(form, field, label_text, class: "label")
end
defp build_input(form, field, opts) do
input_fun_name = opts[:using] || Phoenix.HTML.Form.input_type(form, field)
permitted_attributes = Keyword.drop(opts, [:using])
input_class =
case input_fun_name do
:textarea -> "textarea "
_ -> "input "
end <> form_state_class(form, field)
input_opts =
[{:class, input_class} | permitted_attributes]
|> Enum.reject(&is_nil(elem(&1, 1)))
content_tag :div, class: "control" do
apply(Phoenix.HTML.Form, input_fun_name, [form, field, input_opts])
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-danger"
true -> "is-success"
end
end
end
lib/my_app_web/views/error_helpers.ex
에 Phoenixが生成した error_tag
があるので、そこのCSS クラスも必要に応じて変更します. def error_tag(form, field) do
Enum.map(Keyword.get_values(form.errors, field), fn error ->
content_tag(:span, translate_error(error),
- class: "invalid-feedback",
+ class: "invalid-feedback help is-danger",
phx_feedback_for: input_name(form, field)
)
end)
Bulmaでスタイリングされたォームフィールドを生成する
bulma_input
関数ができました.bulma_input f, :email
사용하는
Phoenix.HTML.Form
の関数を切り替えるoption も受け付けます.# Phoenix.HTML.Form.text_input/3の代わりにPhoenix.HTML.Form.textarea/3を使用したい場合
bulma_input f, :email, using: :textarea
HTML 属性を追加できるようにしました.
bulma_input f, :email, placeholder: "E-mail", autocomplete: "off"
IEx로 전환
TEN 플레이 톤의 폼으로 IEx上でランできる方法を探しました.
Phoenixのソースコードのテストの中にヒントがあったので、その知識で適当にfォームを生成します.
iex
alias MyAppWeb.Accounts
alias MyAppWeb.Accounts.User
changeset = Accounts.change_user_registration(%User{})
form = Phoenix.HTML.Form.form_for(changeset, "/registration", [])
bulma_input(form, :email, placeholder: "E-mail", autocomplete: "off")
|> Phoenix.HTML.Safe.to_iodata()
|> to_string()
|> IO.puts()
<div class="field">
<label class="label" for="user_email">Email *</label>
<div class="control">
<input autocomplete="off" class="input " id="user_email" name="user[email]" placeholder="E-mail" type="email">
</div>
</div>
🎉
Elixir코뮤니티에 더 나아가는 방법은 下記가 오스스메입니다
Elixir코뮤니티 の歩き方 -国内온라인編-
https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian
日本には28箇所のElixir코뮤니티가あります
日程から イベントを探すなら Elixir イベントカレンダー📆
** Elixir아이벤트카렌다 **
https://elixir-jp-calendar.fly.dev/
Reference
이 문제에 관하여(엘릭서 피닉스 폼 필드 원 라이너), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/mnishiguchi/elixir-phoenix-form-field-one-liner-48in
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(엘릭서 피닉스 폼 필드 원 라이너), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mnishiguchi/elixir-phoenix-form-field-one-liner-48in텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)