ハイパーニートプログラマーへの道

頑張ったり頑張らなかったり

【Ruby on Rails】content_tagでmultipleなselectタグを生成する

要するにこういう感じです

https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select_multiple

複数の要素を選択できる select タグを作ろうと

こちらを参考にやってみました

https://rubyplus.com/articles/3411-Tag-View-Helpers-in-Rails-5

  • Rails version 5.1.2
  • Ruby version 2.4.0-p0 (x86_64-darwin16)

Rails console 上で試したので、頭に helper をつけます

array = %w(a b c)

helper.content_tag :select, multiple: true do
  array.collect do |item|  
    helper.content_tag(:option, item)    
  end.join.html_safe  
end  
=> "<select multiple=\"multiple\"><option>a</option><option>b</option><option>c</option></select>"

冒頭のw3schools のコードに合わせてみます。ついでに見やすいように結果を整形しました

array = %w(volvo saab opel audi)

html_output =
helper.content_tag :select, name: 'cars', multiple: true do
  array.collect do |item|  
    helper.content_tag :option, item.capitalize, value: item    
  end.join.html_safe  
end  
=> "<select name=\"cars\" multiple=\"multiple\"><option value=\"volvo\">Volvo</option><option value=\"saab\">Saab</option><option value=\"opel\">Opel</option><option value=\"audi\">Audi</option></select>"

require 'cgi'
puts CGI.pretty(html_output)
<select name="cars" multiple="multiple">
  <option value="volvo">
    Volvo
  </option>
  <option value="saab">
    Saab
  </option>
  <option value="opel">
    Opel
  </option>
  <option value="audi">
    Audi
  </option>
</select>

上記の例だと joinhtml_safe を忘れるのが怖い
collect ではなくeach を使用し、その中で生成されたそれぞれのoption タグをconcat helper で連結します
なおかつ、Rails 5.1 で導入されたtag helper も使ってみます

# Using each with tag helper
helper.tag.select name: 'cars', multiple: true do
  array.each do |item|
    helper.concat(helper.tag.option, item.capitalize, value: item)
  end  
end

参考:

https://rubyplus.com/articles/3411-Tag-View-Helpers-in-Rails-5

New Syntax for HTML Tag helpers in Rails 5.1 | BigBinary Blog

RubyでHTMLを整形する - Ruby Tips!

https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select_multiple