Based on Nguyen answer I created a more robust method that will only modify desired elements and will also reuse the regular expressions.
object Helper {
import views.html.helper.FieldConstructor
implicit val inlineBootstrapConstructor = FieldConstructor(fieldConstructorTemplate.f)
val classRegex = "(?s)(<(?:input|textarea|select)[^>]*\\sclass=[\"'])".r
val noClassRegex = "(?s)(<(?:input|textarea|select))((?:(?!\\sclass=\").+)>)".r
def addClassValue(text: String, classValue: String) = {
val str = classRegex.replaceFirstIn(text, s"$$1$classValue ")
noClassRegex.replaceFirstIn(str, s"""$$1 class="$classValue"$$2""")
}
}
The method is pretty straight forward, it tries to modify the class
element of the first input
, textarea
or select
HTML element and then it creates the class
element if it doesn't already exist. You can add more elements to the input|textarea|select
list if necessary. This works perfect for some bootstrap templates where you have to embed some elements in another div
.
Then, in your template, simply import this method and call it with your class value:
@(elements : helper.FieldElements)
@import Helper.addClassValue
@input = @{ addClassValue(elements.input.toString(), "form-control") }
<div class="@if(elements.hasErrors) {error}">
<label for="@elements.id">@elements.label</label>
<div class="input">
@Html(input)
<span class="errors">@elements.errors.mkString(", ")</span>
<span class="help">@elements.infos.mkString(", ")</span>
</div>
</div>