對抗垃圾信!請您點這裡:

我的E-mail:
我的Skype:My status

2007年6月29日

Rails中實做下拉式選單

太久沒有寫文章了.. 最近接到一個案子.. 剛好讓我重溫Select的使用方法..
嗯.. 結果卡在multiple,不知道是我太想睡還是怎樣.. 居然傻了..
跑去#rubyonrails問,一位名為carpet_the_walls的網友給了我他寫的文章,網址是:
http://shiningthrough.co.uk/Select+helper+methods+in+Ruby+on+Rails
在此先謝謝carpet_the_walls (Thank you, carpet_the_walls)

來做個Memo.. 不然又忘記了..
在Rails中真的有一堆Select helper可以用.. 不只carpet_the_walls混淆,連我也模糊不清!
常見的有三個..
select, select_tag, collection_select(其餘的什麼select_date那些不談)
我們先來看看一個基本的下拉式選單骨架

<select name="selection">
  <option value="1">Opt1</option>
  <option value="2">Opt2</option>
</select>
在一個下拉式選單中,有一些是必備的資訊,像是"name"、"value"與"text"三個,在回傳資訊給Server時,"name"將是接收資訊用的,而"value"會傳回被選的值,而"text"則是使用者會看到的字,依上面的例子來講,Opt1、Opt2這兩個就是屬於"text"

開始講講那三種Select helper

select:
  select(object, method, choices, options = {}, html_options = {})
  在ActionView::Helpers::FormOptionsHelper中定義

  • object是一個實體化變數,這裡很明顯的就是要擺上model物件嘛!
  • method則是object的一個屬性,也是資料表中的對應欄位
  • choices就是要被選的選項,可以是陣列或者是雜湊(Hash)
  • options與html_options則是一些選項
在這邊來舉個例子吧
<%= select("project", "teacher_id", @teachers.collect{|t| [t.name, t.id]}, { :include_blank => false }) %>
<%= select("project", "student_id", {"CFC" => '1', "EF" => '2'}) %>
第一個例子中,@teachers在Controller是這樣的
@teachers = Teacher.find(:all, :select => 'id, name')

select_tag:
  select_tag(name, option_tags = nil, options = {})
  在ActionView::Helpers::FormTagHelper中定義

如果你很喜歡手動打option的話.. 那用select_tag準沒錯啦!
在select_tag中,name將會是params所接收值所用的鍵
直接看範例
<%= select_tag 'user', "<option>CFC</option>" %>
這時在Controller中將會用params[:user]來接收傳過來的值
但是select_tag也可以搭配options_for_select或者options_from_collection_for_select一起使用.. 來看一個範例吧
<%= select_tag('sid[]', options_from_collection_for_select(@students, 'id', 'name'), :multiple => true)%>
因為加上了:multiple,所以可以接受多值選擇,這時在Controller接收到的sid將會是一個陣列,這也是我所卡住的地方.. (( 真丟臉

collection_select:
  collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
  在ActionView::Helpers::FormOptionsHelper中定義

如果資料來源是從資料庫來的話,可以使用這個來做下拉式選單。
這個Object不用我說,就是你的model
method呢?當然就是欄位啦
其實嚴格說起來,這只是select+options_from_collection_for_select的組合啦!
範例:
<%= collection_select(:payment, :id, @payments, :id, :name, options ={:prompt => "-Select a continent"}, :class =>"payment") %>

再次謝謝原作者carpet_the_walls:)

2 則留言:

匿名 提到...

CFC Honey~~~~ [你可以叫我Darling沒差XD]

select_tag用在form中最大的問題會出現在update中,因為它沒有自動的在option的tag中下selected,所以建立後再重新編輯時不會轉跳為已經設定的值|||

collection_select就沒這個問題,可是它最大的問題在"不能sort"|||[like"郵遞區號",不能sort的問題就超級大|||,目前沒捷徑解...都用自己寫的select_tag + 目前值的判斷來增加selected]~ so~ Honey~ 搞個可以自訂且容易使用教學來吧~~ XD

final~ 與其用在select下用":multiple => true",我會建議你改成用check box,而且check box經過一程度hack的話會有很高的活性的(像是關聯模型,以check box設定是否有這關聯,在加上select_tag來做權限設定[這裡會用到二維陣列傳值...],加上該項目的圖片和描述,全部包成小小的一格用css的float排版就很漂亮哩,有需要的話可以讓你觀摩XD)

CFC 提到...

你要叫我打你? 沒問題的= v =

我之所以要用下拉式選單就是因為會有很大量的資料要選
不想佔用版面= =|||