ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

【Play Framework】scala初心者に教える、PlayへBootstrapを導入するときのFormの組み替え方法

スポンサードリンク

http://www.flickr.com/photos/83798814@N07/9405945182
photo by DJ AMatterFact


また、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ってなんだよ!!(´;ω;`)ブワッ


最初メソッドを定義して、それを作らないといけないのかなと色々考えていましが、結局よくわかりません。


とりあえず、これでできるようになりました。。。。。


Scalaってドットインストールがないから、勉強サイトが中々見つからないの。できれば動画がいいお(^ω^ = ^ω^)

ハマった時のやったメモ


デバッグができないのが辛かった。eclipseでやってて、多分やりかたがあるんだろうけど、わからない。


ScalaJavaのクラスも使えるので、こうしました。

@(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,))


こんなのがでてきて、「あ、一応値は入っているのね。」と、いうことがわかりました。