Search code examples
templatesscalaplayframework-2.0

Is it possible to override form helpers?


Using the doc, I can set my own helper for the layout surrending my field, but I'd like to personalize also some fields given by play.

The main reason is for Twitter Bootstrap 2, where I need to change (in checkbox.scala.html)

@input(field, args:_*) { (id, name, value, htmlArgs) =>
    <input type="checkbox" id="@id" name="@name" value="@boxValue" @(if(value == Some(boxValue)) "checked" else "") @toHtmlArgs(htmlArgs.filterKeys(_ == 'value))>
    <span>@args.toMap.get('_text)</span>
}

to :

<label class="checkbox">
    <input type="checkbox" name="@name" id="@id" value="@boxValue" @(if(value == Some(boxValue)) "checked" else "") @toHtmlArgs(htmlArgs.filterKeys(_ == 'value)) />
    @args.toMap.get('_text)
</label>

How can I do that?


Solution

  • I finally did it like this :

    I created a package views.helpers.form, that contains :

    bootstrap.scala.html :

    @(elements: helper.FieldElements)
    
    <div class="control-group@if(elements.hasErrors) { error}">
        <label class="control-label" for="@elements.id">@elements.label(elements.lang)</label>
        <div class="controls">
            @elements.input
            @elements.infos(elements.lang).map { info =>
                <span class="help-inline">@info</span>
            }
            @elements.errors(elements.lang).map { error =>
                <span class="help-block">@error</span>
            }
        </div>
    

    checkbox.scala.html :

    @**
     * Generate an HTML input checkbox.
     *
     * Example:
     * {{{
     * @checkbox(field = myForm("done"))
     * }}}
     *
     * @param field The form field.
     * @param args Set of extra HTML attributes ('''id''' and '''label''' are 2 special arguments).
     * @param handler The field constructor.
     *@
    @(field: play.api.data.Field, args: (Symbol,Any)*)(implicit handler: helper.FieldConstructor, lang: play.api.i18n.Lang)
    
    @boxValue = @{ args.toMap.get('value).getOrElse("true") }
    
    @helper.input(field, args:_*) { (id, name, value, htmlArgs) =>
        <label class="checkbox">
            <input type="checkbox" id="@id" name="@name" value="@boxValue" @(if(value == Some(boxValue)) "checked" else "") @toHtmlArgs(htmlArgs.filterKeys(_ == 'value))>
            @args.toMap.get('_text)
        </label>
    
    
    div>
    </div>
    

    And in my template, all I have to do is :

    @import helper.{FieldConstructor, inputText, inputPassword} @** Import the original helpers *@
    @import helpers.form.checkbox @** Import my helpers *@
    @implicitField = @{ FieldConstructor(helpers.form.bootstrap.f) }
    

    And voilà! It works!