6.Radio、Checkboxについて

Lift初心者が「RadioやCheckboxは鬼門」と声をそろえたのを聴いたことがありますが、そんなことはないので落ち着いてください。

シンプルなRadioボタンの実装はこんな感じ

class ComplexRadio {
  object radioChoice extends RequestVar("しない")
  def simple = {
    "type=radio" #>
      SHtml.radio(Seq("する","しない"), Full(radioChoice), radioChoice(_) ).toForm &
    "type=submit" #> SHtml.submit("save", () => () )
  }
}

ですが、ちょっと他のHTMLコンポーネントと作法が違っていて、toFormというメソッドを用いてHTMLを生成しています。
このtoFormは、単なる簡易メソッドなので、「縦並びを横並びにしたい」「3個毎改行表示したい」「その他を選んだときテキスト入力をつけたい」というニーズには向いていません。

SHtml.radio が生成するのは、net.liftweb.http.SHtml.ChoiceHolder であり、holder.itemsで全要素(Seq[ChoiceItem])、インデックスやキーで各HTML要素(NodeSeq)を取り出せることを覚えておくと応用がききます。

横並びにして、ラベルに飾りをつけるなら、

  def layout = {
    val holder =
    SHtml.radio(Seq("する","しない"), Full(radioChoice), radioChoice(_) )

    "type=radio" #> holder.items.map( i =>
      i.xhtml ++ <span> -- {i.key}</span>
    ) &
    "type=submit" #> SHtml.submit("save", () => () )
  }

ある選択肢にテキスト入力を付加するなら、

  def render = {
    val holder =
    SHtml.radio(Seq("する","しない"), Full(radioChoice), radioChoice(_) )

    "type=radio" #> {
      holder("する") ++ <span>する</span> ++
      SHtml.text( txt, txt(_) ) ++ <br/> ++
      holder("しない") ++ <span>しない</span>
    } &
    "type=submit" #> SHtml.submit("save", () => () )
  }

などと、多少ややこしくはなりますが、許容範囲かと思います。


とはいえ、とっても基本的なところが鬼門

radioボタンのユーザビリティを高めるために、 label for を使って、テキストをクリックしてもRadioを選択できるようにするものだと思いますが、それをやるためのAPIは用意されていません!

SHtml.radioが生成する input radio に それぞれ単独のdom idを付与できない、という欠陥があります。が、それも解決できます。2つ紹介します。

1つは、scala.xml.NodeSeq を scala.xml.Elemにキャストして % メソッドを使うやり方。

  def withlabel1 = {
    val holder =
    SHtml.radio(Seq("する","しない"), Full(radioChoice),radioChoice(_))

    "type=radio" #> {
      ( holder("する").asInstanceOf[Elem] %
        new UnprefixedAttribute("id","radio1",Null) ) ++
      <label for="radio1">する</label> ++
      ( holder("しない").asInstanceOf[Elem] %
        new UnprefixedAttribute("id","radio2",Null) ) ++
      <label for="radio2">しない</label>
    } &
    "type=submit" #> SHtml.submit("save", () => () )
  }

もう一つは、CssSelを応用して、scala.xml.NodeSeq に変換をかけるやり方。コッチの方が応用が効くかもしれません。

  def withlabel2 = {
    def addDomId(domid:String) = ("input [id]" #> domid)
    val holder =
    SHtml.radio(Seq("する","しない"), Full(radioChoice), radioChoice(_) )

    "type=radio" #> {
      addDomId("radio3")(holder("する")) ++
      <label for="radio3">する</label> ++
      addDomId("radio4")(holder("しない")) ++
      <label for="radio4">しない</label>
    } &
    "type=submit" #> SHtml.submit("save", () => () )
  }

いやはやこうして見ると、やはり鬼門でした。



このシリーズ

1.Lift再入門
2.Snippetメソッドとして許される型
3.ログインFORM - S.param使ったら負け
4.サーバーサイドバリデーションとサーバサイド関数
5.行列型の編集FORM
6.Radio、Checkboxが鬼門?
7.Ajax Form
8.javascriptからsubmitできない

動作確認サンプルコード github
Simply Lift(必読)


同じカテゴリのエントリ
1.Lift再入門 / 8.javascriptからsubmitできない / 7.Ajax Form / 6.Radio、Checkboxについて / 5.行列型の編集FORM / 4.サーバーサイドバリデーションとサーバサイド関数 / 3.ログインFORM - S.param使ったら負け / 2.Snippetメソッドとして許される型 / sbt0.12.xで依存jar抽出タスク / scala2.10+lift2.5+NetBeans7.2 / Scalaで入門関数プログラミング / reactive-webを試してみました / Lift2.2M1のテンプレート機能 / Scala Compiler Plugin / View Bound/Context Bound / ScalaZa01参加してきました / Akka Frameworkチュートリアルの次 / Akka Frameworkチュートリアルその2 / Akka Frameworkチュートリアル / LiftでJCaptcha / Url Rewrite Filter / sbt-android-plugin / Android SDK for Scala / 祝Lift2.0リリース / Liftの携帯対応まとめ / Scala2.8への移行 / Lift 2.0-scala280-SNAPSHOT/sbt0.7.1 / Scalaお絵かき環境 - Kojo / Lift+Quartzでバッチ / Scala&Liftを採用した理由 / Liftでdate_select系ヘルパーを作る / LiftでAjax / LiftのSubmitかしこい / lift-mapperのpaginateを使う / snippetをspecする / Lift Mapperを拡張する / LiftのDBをMySQLに / Liftプロジェクト環境を整える / Scala本読み比べてみました / NetBeans6.7&scala / じつはScalaはライトな言語 / Scalaバザ~ル / lift1.0所感 / specsを読む / implicit def / ScalaならNetBeansがサイコー / scala勉強会@東北がスタート / それでも俺はLiftをやるってのか / Scala&Liftセットアップ / ブログリニューアル /
コメント

コメントしてください

closed.