Ruby
Rails
activeadmin
formtastic

Formtasticでオリジナルinputを作ってみた

More than 1 year has passed since last update.

シチュエーション

Formtasticは最初から多数のinput形式が利用可能で、大半の要件はその範囲内で片付きますが、たまにその範囲を逸脱したい場合があり、そのために自作inputを作れるようになっています。この機能を使って、「textareaが2つあるinput」を作ってみました。

実装

app/inputs/double_text_input.rb
class DoubleTextInput < Formtastic::Inputs::TextInput
  def to_html
    # FIXME: gemとかに切り出すときは width:calc(40% - 22pt) というstyleを適用させる
    input_wrapping do
      label_html <<
      builder.text_area(method, input_html_options) <<
      build_second_text_area
    end
  end

  private
  def build_second_text_area
    original_method = method
    self.method = :"#{original_method}_2"
    text_area = builder.text_area(method, input_html_options)
    self.method = original_method
    text_area
  end
end

呼ぶときは f.input :description, as: :double_text という感じで呼びます。そうすると

<li class="double_text input optional" id="item_description_input">
  <label for="item_description" class="label">Description</label>
  <textarea rows="20" id="item_description" name="item[description]">
  </textarea>
  <textarea rows="20" id="item_description_2" name="item[description_2]">
  </textarea>
</li>

こんな感じのhtmlが出力されます。見ての通り、2つ目のtextareaのnameに_2をつけてるだけなので、受け取る方が_2をつけた項目を受け取れるようになっている必要があります。

解説

概要

READMEに記載の通り、to_htmlメソッドで返す文字列がそのinputの部分htmlとして使用されるので、ここをいじります。
今回は普通のTextInputのtextareaのうしろに2つ目のtextareaを追加しています。
Formtasticのメソッドの切り方に起因して、ちょっと追加する修正でも親クラスのメソッドをコピーして修正するようなやり方が必要になるケースがままあります。

build_second_text_areaメソッドの処理内容

一時的にmethodというインスタンス変数(Inputクラス共通でattr_accessorが定義してあります)の内容を書き換えています。これには以下の2つの目的があります。

  • textareaのname属性(builder.text_areaの第1引数が使われる)が被らないようにすること
  • input_html_optionsメソッドの中でmethod変数をtextareaのid属性を構成するのに使っていて、そのままtextareaを出力してしまうと、2つのtextareaのid属性が被ってしまうので、それを避けること