`datalist_tag` ヘルパーの追加によるHTML datalist要素の生成サポート
Action Viewに datalist_tag ヘルパーが追加され、HTML <datalist> 要素をRailsの流儀で簡潔に生成できるようになりました。既存の options_for_select と同じ書式でオプションを指定できるため、学習コストを抑えながら導入できます。
背景
これまでRailsで <datalist> 要素を生成するには、content_tag をネストして記述する必要があり、テンプレートが冗長になっていました。PRの動機として示されているコードは、datalist 本体と各 option の両方に content_tag を使い、データ属性も手動で設定する必要がある煩雑な実装です。
<%= content_tag(:datalist, nil, id: :payees_datalist) do %>
<% @payees.each do |payee| %>
<%= content_tag(:option, nil, value: payee.name, data: { id: payee.id }) %>
<% end %>
<% end %>
select_tag や options_for_select のような専用ヘルパーが <select> 向けには存在するにもかかわらず、オートコンプリートUIに利用される <datalist> には対応するヘルパーがなく、開発者が毎回ボイラープレートを書く必要がありました。
技術的な変更
datalist_tag は form_tag_helper.rb に18行で実装されており、内部で options_for_select を呼び出すシンプルな設計です。
実装は以下の通りです:
def datalist_tag(id, option_tags = nil, html_options = {})
option_tags ||= ""
content_tag("datalist", options_for_select(option_tags), { "id" => id }.update(html_options.stringify_keys))
end
option_tags パラメータは options_for_select の container 引数と同じ書式を受け付けます。文字列の配列、ラベルと値のハッシュ、[ラベル, 値, HTMLオプション] 形式の配列など、複数の指定方法が使えます:
# シンプルな文字列配列
datalist_tag('countries_datalist', %w[Argentina Brazil Chile])
# ラベルと値を分けたハッシュ
datalist_tag('countries_datalist', { 'Argentina' => 'AR', 'Brazil' => 'BR' })
# HTMLオプション付きの配列(ラベル・値・属性)
datalist_tag('countries_datalist',
['Argentina', ['Brazil', { class: 'brazilian_option' }], ['Chile', 'CL', { disabled: true }]],
{ class: 'sa-countries-sample' }
)
# => <datalist id="countries_datalist" class="sa-countries-sample">
# <option value="Argentina">Argentina</option>
# <option value="Brazil" class="brazilian_option">Brazil</option>
# <option value="CL" disabled="disabled">Chile</option>
# </datalist>
テストは form_tag_helper_test.rb に73行追加され、空のdatalist、シンプルな配列、ラベル/値ハッシュ、ラベル/値/HTMLオプションの配列など、各書式を網羅的にカバーしています。
設計判断
options_for_select の書式を再利用する設計 により、既存の select_tag ユーザーは追加の学習なしに datalist_tag を使いこなせます。option_tags のデフォルト値を nil ではなく空文字列 "" にフォールバックすることで、引数なし呼び出しでも <datalist id="..."></datalist> という有効なHTMLが生成されます。
また、id をキーワード引数でなく第一引数として受け取る設計は、<datalist> 要素がリスト識別に id を必須とするHTML仕様(<input list="id"> で参照する)を反映しています。html_options は stringify_keys で正規化してから id とマージされるため、シンボルキーと文字列キーのどちらで渡しても一貫して動作します。
まとめ
datalist_tag の追加は、<datalist> 要素を扱う際に必要だった content_tag のネストをAction Viewのヘルパー体系で吸収した変更です。options_for_select との書式統一により、既存のフォームヘルパーの知識をそのまま活かしつつ、オートコンプリートUIの実装を宣言的に記述できるようになります。