如何为动态生成的内容编写自定义表单助手模板?

时间:2015-06-13 20:01:17

标签: html css twitter-bootstrap scala playframework

我有一些测验系统,用户可以通过单选按钮显示问题和几个答案选项。

但是当我使用一个通过列表填充的inputRadioGroup的帮助器时,它看起来不再漂亮了(比如Twitter Bootstrap)。 radiobuttons是内联的,而它们应该在彼此之下。实际上我想将图标更改为更漂亮的按钮。

这就是目前的情况:

Example

因此我尝试编写自己的自定义表单助手,但一直卡住。我觉得很难理解这个文档: https://www.playframework.com/documentation/2.3.x/JavaFormHelpers

首先我创建了一个名为 myFieldConstructorTemplate.scala.html

的新模板
@(elements: helper.FieldElements)

<div class="@if(elements.hasErrors) {error}">
<label for="@elements.id">@elements.label</label>
<div class="input">
    @elements.input
    <span class="errors">@elements.errors.mkString(", ")</span>
    <span class="help">@elements.infos.mkString(", ")</span>
</div>
</div>

将其保存到/ views-folder。然后尝试在我的视图类 quiz.scala.html:

中使用它
@import helper._
@import helper.twitterBootstrap._

@(questionList: List[Question], answerList: List[Answer], answerRadioForm: Form[Answer])

@helper.form(action = routes.Application.nextQuizPage(), 'id -> "answerRadioForm"){
    @helper.inputRadioGroup(
    answerRadioForm("Answer"),
    options = answerList.map(answer => answer.answerID.toString -> answer.answerText),
    '_label -> "Answer",
    '_error -> answerRadioForm("answerID").error.map(_.withMessage("select answer")))
<button type="submit" class="btn btn-default" value="Send">
    Next Question
</button>
}
@implicitField = @{ FieldConstructor(myFieldConstructorTemplate.f) }
@inputText(answerRadioForm("questionID"))

如果我把它放到我的模板中,我会收到not found: value implicitField - 错误。

那么如何设法将我的无线电按钮的外观改为底部并看起来像Twitter Bootstrap?

[EDIT1]:我已将导入的顺序更改为建议的版本:

@(questionList: List[Question], answerList: List[Answer], answerRadioForm: Form[Answer])

@import helper._
@implicitField = @{ FieldConstructor(myFieldConstructorTemplate.f) }
@import helper.twitterBootstrap._

然后我收到了这个错误:

ambiguous implicit values: 
both method implicitField of type => views.html.helper.FieldConstructor 
and value twitterBootstrapField in package twitterBootstrap of type 
=> views.html.helper.FieldConstructor match expected type 
views.html.helper.FieldConstructor

我认为这与我将答案导入radiobuttons的方式有关?

[EDIT2]: 现在是导入的顺序:

@(questionList: List[Question], answerList: List[Answer], answerRadioForm: Form[Answer])

@import models.Question
@import models.Answer

@import helper._
@implicitField = @{ FieldConstructor(myFieldConstructorTemplate.f) }

有了这个,程序就会编译。但是无线电按钮看起来仍然一样。所以我试图改变设计,这不太合适。现在看起来所有的无线电按钮都融合成一个:

Monty Python

这是我的模板类 myFieldConstructorTemplate.scala.html

@(elements: helper.FieldElements)

<div class="btn-group", data-toggle="buttons">
<label for="@elements.id">@elements.label</label>
<div class="input">
    <label class="btn btn-primary">
    @elements.input
    <span class="errors">@elements.errors.mkString(", ")</span>
    <span class="help">@elements.infos.mkString(", ")</span>
</label>
</div>
</div>

[EDIT3]:我根据to the last answer更改了课程,但仍然将无线电按钮融为一体。所以我想指出的是,我并没有注意使用inputRadioGroup from the playframework helper,如果有另一个解决方案工作原理相同并且看起来几乎像bootstrap,我很乐意使用它。似乎改变助手并不容易/直观。我感谢任何形式的帮助!

3 个答案:

答案 0 :(得分:1)

RewriteEngine On RewriteRule ^example/products/category/?category= /example/home/page-category.php [L,R=301] - 定义移至文件顶部:

implicitField

这可以确保隐含值在需要的地方可用。

答案 1 :(得分:1)

始终将params保留在模板顶部并删除以下import语句@import helper.twitterBootstrap._这将与您自己的字段构造函数冲突。

@(questionList: List[Question], answerList: List[Answer], answerRadioForm: Form[Answer])

@import helper._
@implicitField = @{ FieldConstructor(myFieldConstructorTemplate.f) }

希望它能解决你的问题。

答案 2 :(得分:1)

Twitter Bootstrap结构需要准确。

btn-group类包裹在inputRadioGroup帮助器周围,如下所示:

<div class="btn-group" data-toggle="buttons">
@helper.inputRadioGroup(
    answerRadioForm("Answer"),
    options = answerList.map(answer => answer.answerID.toString -> answer.answerText),
    '_label -> "Answer",
    '_error -> answerRadioForm("answerID").error.map(_.withMessage("select answer")))
</div>  

然后用以下代码替换模板:

@(elements: helper.FieldElements)

<label class="btn btn-primary">
    @elements.input @elements.label
</label>

<span class="errors">@elements.errors.mkString(", ")</span>
<span class="help">@elements.infos.mkString(", ")</span>

一般而言,也许它会以另一种方式引起兴趣。当您使用fooForm("myField"...)时,您可以在fooForm("myField[@i]"...)循环中使用for@i是一个从0开始的计数器,但输入的数量却很多。然后你可以自己绘制完整的HTML而不是使用隐式值。

顺便说一句,关于所有这些的Scala版本的文档比Java版本有更多的信息。见here。它提供了有关inputRadioGroup的更多信息,而不是文档的Java版本,但仍然非常有用,可以更好地理解所有这些。

有些Play Bootstrap plugin在GitHub上有可用的代码,它也很有用,特别是因为它也使用隐式值。

更新

这里有几个GitHub项目展示了如何实现这个目标:

结果截图:

enter image description here