また、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,))
こんなのがでてきて、「あ、一応値は入っているのね。」と、いうことがわかりました。
