I have some sort of quiz system, where to user gets shown a question and several answer-options with radio-buttons.
But as I am using a helper for a inputRadioGroup that gets filled via a list, it does not look pretty anymore (like Twitter Bootstrap). The radiobuttons are inline, while they should be underneath each other. And actually I would like to change the icon to a prettier button.
This is how it looks at the moment:
Therefore I tried to write my own custom form helper, but keep getting stuck. I find it frustratingly hard to understand the documentation for this:
https://www.playframework.com/documentation/2.3.x/JavaFormHelpers
First I created a new template named 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>
Saved it to the /views-folder. Then try to use it in my view class 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"))
If I put this into my template, I get a not found: value implicitField
-error.
So how can I manage to change the appearance of my radiobuttons to underneath and looking like Twitter Bootstrap?
[EDIT1]: I have changed the order of the imports to the suggested version:
@(questionList: List[Question], answerList: List[Answer], answerRadioForm: Form[Answer])
@import helper._
@implicitField = @{ FieldConstructor(myFieldConstructorTemplate.f) }
@import helper.twitterBootstrap._
I get this error then:
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
I think this has to do with the way I import the answers into the radiobuttons?
[EDIT2]:
The order of the imports is now:
@(questionList: List[Question], answerList: List[Answer], answerRadioForm: Form[Answer])
@import models.Question
@import models.Answer
@import helper._
@implicitField = @{ FieldConstructor(myFieldConstructorTemplate.f) }
With this, the program compiles. BUT the radiobuttons still look the same. So I tried to change the design, which does not quite work. It looks now like all the radiobuttons are melted into a single one:
Here is my template class 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]: I have changed my class according to the last answer, but still the radiobuttons are melted into each other. So I want to point out that I am not fixated on using the inputRadioGroup from the playframework helper, if there is another solution that works the same and looks almost like bootstrap, I would gladly use that. It seems that changing the helper isnt that easy / intuitive. I appreciate any form of help!
3
Answers
Move the
implicitField
-definition to the top of the file:This makes sure the implicit value is available where it’s needed.
Always keep params on top of template and remove the following import statement
@import helper.twitterBootstrap._
this will conflict with your own field constructor.Hope it resolves your issue.
The Twitter Bootstrap structure needs to be accurate.
Wrap the
btn-group
class around theinputRadioGroup
helper like so:Then replace the template with:
In general, perhaps it’d be of interest another way of doing it. When you use
fooForm("myField"...)
, you can usefooForm("myField[@i]"...)
in afor
loop where@i
is a counter going from 0 to however many inputs there are. Then you can yourself sketch out the full HTML instead of using implicit values.By the way, the documentation with the Scala version about all this has lots more information than the Java version. See here. It has more information on
inputRadioGroup
than the Java version of the documentation but still very useful reading for better understanding of all this.Some Play Bootstrap plugin has code available on GitHub that is also useful reading especially as it uses implicit values also.
UPDATE
Here’s a couple of GitHub projects showing how to achieve this:
Screenshot of the result: