2012-05-12

sinatraで複数選択のcheckboxの値を取得する

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
sinatraに限らないのかもしれませんが、複数選択する場合のcheckboxの取り扱いです。

ケース1
一番単純なのは、それぞれ別の名前のチェックボックスを用意することだと思います。
以下のような感じです。

好きな色は?
<input type="checkbox" name="like_red" value="red">赤
<input type="checkbox" name="like_blue" value="blue">青
<input type="checkbox" name="like_green" value="green">緑

この場合は、paramsの値をチェックすればOKです。
チェックされているときだけ、値が入りチェックがなければ値が入っていません。

チェックされていれば
params['like_red']
で"red"が取れます。


ケース2
他にparamsで配列で受け取れるようにする方法もあります。

以下のような感じです。
nameの書き方がポイントです。

好きな色は?
<input type="checkbox" name="like[]" value="red">赤
<input type="checkbox" name="like[]" value="blue">青
<input type="checkbox" name="like[]" value="green">緑

この場合は、params["like"]にチェックした値が配列で入っています。
赤と青がチェックされていれば
params['like']
で['red','blue']が取れます。


ケース3
他にnameが同じになっているケースがあります。
以下のような感じです。

好きな色は?
<input type="checkbox" name="like" value="red">赤
<input type="checkbox" name="like" value="blue">青
<input type="checkbox" name="like" value="green">緑

この場合は、仮に複数の値がチェックされていてもparams["like"]で取れるのは、どれか一つだけです。
なので上記二つの書き方に変えるのがよいとは思うのですが、この場合でsinatraで受け取る方法です。

以下のような感じで受け取れます。
以下ではとりあえず複数受け取った値を,で連結しています。

  data = {}
  env["rack.request.form_vars"].split("&").each do |d|
    (k,v) = d.split("=")
    k = URI.decode(k).toutf8
    v = URI.decode(v).toutf8 unless v.nil?
    if data[k].nil?
      data[k] = v
    else
      data[k] = data[k] + ", " + v
    end
  end

これで赤と青がチェックされていた場合は、
data['like']
で"red,blue"が受け取れます。


コメントを投稿