また、Playに戻ってきました。CakePHPも引き続き触っていますけどね。
さてこの1週間。すごい悩んでいました。implicitFieldConstructor
の扱い方に(´;ω;`)ブワッ
ちゃんと理解はしていませんが、やっとできたのでメモ。
環境
[project] $ playVersion [info] 2.3.9
Play FrameworkでBootstrapを使いたい
Play Frameworkさんは優秀で、build.sbtに値を追加、routesにurlを登録したら、Bootstrapが使えるようになります! さすがやで。
- build.sbt
libraryDependencies ++= Seq( javaJdbc, javaEbean, cache, javaWs, filters, "mysql" % "mysql-connector-java" % "5.1.34", "commons-io" % "commons-io" % "2.4", "org.webjars" %% "webjars-play" % "2.3.0", // ここと "org.webjars" % "bootstrap" % "3.2.0" // ここを追加 )
- conf/routes
# bootstrap GET /webjars/*file controllers.WebJarAssets.at(file)
./activator update
すると、Bootstrapが使えるようになります。
しかし問題が発生
このままうまくいけばよかったんですけども、問題が。
@helper.form
が、Bootstrapの形式に合わせてくれません。
こういうフォームが理想です。
<div class="form-group"> <label for="exampleInputEmail1">Email address</label> <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email"> </div>
しかし、@helper.inputText()
はこう出力される
<dl class=" " id="username_field"> <dt><label for="username">ユーザー名</label></dt> <dd> <input type="text" id="username" name="username" value="" class="form-control"> </dd> <dd class="info">Required</dd> </dl>
dl dt dd
いらないよ。このままじゃ使えない。どげんかせんといかん。
ということでやり方を探してみたら、発見しました。
独自@formを定義する
Formを生成しているのはFieldConstructor
というクラスらしいが、これをimplicit
することにより、独自のformを定義することができるとか。
よくわかりません(∩´∀`)∩ワーイ
implicit
ってなんね? それ? あんまり理解していませんが、とりあえずリンクを貼り付けておきます。( ´∀`)つ ミ
Scala の implicit parameter は型クラスの一種とはどういうことなのか - 猫型の蓄音機は 1 分間に 45 回にゃあと鳴く
色々なリンクを探しましたが、とりあえずこうすればいいんだな!
独自のhelperファイルを作って、それをimplicitで読み込む(?)ようにしました。
- app/views/index.scala.html
@(formTest: play.data.Form[models.Test]) @implicitFieldConstructor = @{ FieldConstructor(bootstrapForm.f) } <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel='stylesheet' href='@routes.WebJarAssets.at(WebJarAssets.locate("css/bootstrap.min.css"))'> <title>Login</title> </head> <body> <div id="header"> <h1 class="col-md-4 col-md-offset-4">テストフォーム</h1> </div> @form(action = routes.Application.test()) { @(inputText(field = formTest("test"), 'class -> "form-control", 'name -> "test", '_label -> "テスト")) <div class="row"> <button type="submit" class="btn btn-primary col-md-2 col-md-offset-5">送信</button> </div> } </body> </html>
- app/views/helper/bootstrapForm.scala.html
@(elements: helper.FieldElements) <div class="row"> <p class="form-group col-md-4 col-md-offset-4"> <label for="user_login">@elements.label</label> @elements.input </p> </div>
個人的にビビったのはこれ
@implicitFieldConstructor = @{ FieldConstructor(bootstrapForm.f) }
なんだよ!bootstrapForm.f
って! f
ってなんだよ!!(´;ω;`)ブワッ
最初メソッドを定義して、それを作らないといけないのかなと色々考えていましが、結局よくわかりません。
とりあえず、これでできるようになりました。。。。。
ハマった時のやったメモ
デバッグができないのが辛かった。eclipseでやってて、多分やりかたがあるんだろうけど、わからない。
@(elements: helper.FieldElements) @import play.Logger; <div class="row"> @play.Logger.debug(elements.toString()); </div>
[debug] application - FieldElements(test,Field(null,test,ArrayBuffer((constraint.required,Buffer())),None,ArrayBuffer(),Some()), <input type="text" id="test" name="test" class="form-control"/> ,Map('class -> form-control, 'name -> test, '_label -> テスト),Lang(ja,))
こんなのがでてきて、「あ、一応値は入っているのね。」と、いうことがわかりました。