Form validation and form helper

2019-03-08 04:35发布

问题:

I still struggle with the form validation and form helpers in Play 2.0. I have this login screen that I use together with the Twitter Bootstrap. So my login form looks like this:

    @helper.form(routes.Application.authenticate, 'class -> "form-horizontal") {
    <fieldset>
    <legend>@Messages("login")</legend>

            @if(loginForm.hasGlobalErrors) { 
                <div class="alert alert-error">
                <a class="close" data-dismiss="alert">×</a>
                    @loginForm.globalError.message
                </div>
            }
            @if(flash.contains("success")) {
                <div class="alert alert-success">
                <a class="close" data-dismiss="alert">×</a>
                    @flash.get("success")
                </div>
            }

            @inputText(loginForm("email"), '_label -> "Email")
            @inputText(loginForm("password"), '_label -> Messages("login.password"))


            <div class="form-actions">
                <button type="submit" class="btn btn-success">@Messages("button.doLogin")</button>
                @Messages("or")
                <a class="btn btn-warning" href="routes.LandingPage.index">@Messages("button.doCancel")</a>
            </div>              
    </fieldset>
    }

And my twitter bootstrap field looks like following:

@(elements: helper.FieldElements)

@**************************************************
* Generate input according twitter bootsrap rules *
**************************************************@
<div class="control-group @if(elements.hasErrors) {error}">
    <label class="control-label" for="@elements.id">@elements.label</label>
    <div class="controls">
        @elements.input
        <span class="help-inline">@elements.infos.mkString(", ")</span> 
    </div>
</div>    

This is the output:

What I do not understand:

1, Why is the help text visible all te time (on the right side of the input field)

The help text comes from @elements.infos.mkString(", "). So deleting this line will delete the help text. Or you can pass an empty string to supress the helptext being visible: '_help -> ""

2, How to show only the help text if an error occurs?

Help text can be added when using this code: @elements.errors(elements.lang).mkString(", ")

3, What are the possible parameters to pass to an input text field? I want to pass the class name as well, but I do not know how...

I can define my custom arguments to pass (i.e. class or placeholders): class="@elements.args.get('_class) and then I can pass it like this: '_class -> "classname"

4, Can I define more than one implicitFieldConstructors in one template part? Because for the checkboxes I want another fieldConstructor compared to the imput boxes and textarea, but how to do this?

Example for this: In the computer-database sample a Twitter bootstrap field is defined, but then it is used as follows:

@inputText(loginForm("email"), '_label -> "Email")

Why is the name here inputText and not just input? Because there is also an input.scala.html?

So, If I want to make a fieldhandler for the checkbox, how to use this? The following format is giving me errors:

@checkBoxHandler = @{ FieldConstructor(s2ftheme.constructors.checkbox.render) }
@checkbox(loginForm("remember"), '_label -> Messages("login.remeberme"))(handler = implicitFieldConstructor)

I get the error message:

not enough arguments for method apply: (implicit handler: views.html.helper.FieldConstructor, implicit lang: play.api.i18n.Lang)play.api.templates.Html in object checkbox. Unspecified value parameter lang.

I think I am missing the concept here... Thanks.

回答1:

The info text comes from @elements.infos.mkString(", "). To show the errors, you should use @elements.errors(elements.lang).mkString(", ") instead.

The correct parameter to change the infos content would be help (this is a bit inconsistent, you have to read the source to realize this) so if you want to use the built-in bootstrap fields but suppress the infos, you'd pass '_help -> "".

Edit for #4:

Here's how you should call your specific checkbox:

@checkbox(loginForm("remember"), '_label -> Messages("login.remeberme"))(handler = implicitFieldConstructor, implicitly[Lang])

And yes, @input means there's a template called input.scala.html. It's the basic template for all input helpers.

To understand why and how this works, you should dive a little deeper into Play 2.0 and Scala (esp. implicit arguments).



回答2:

  1. Because of this line <span class="help-inline">@elements.infos.mkString(", ")</span>. You are displaying the information about the field there. Remove it to don't display the information.
  2. Add this code:

    @if(elements.hasErrors) {
        <span class="help-inline">@elements.infos.mkString(", ")</span> 
    }
    
  3. To set the classname: add this to your Twitter Bootstrap field: class="@elements.args.get('_class). And in your login form add the class parameter, like this: @inputText(loginForm("email"), '_label -> "Email", '_class -> "classname")

To understand the concept, take a look at the source code: https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/views/helper/defaultFieldConstructor.scala.html



回答3:

I'm in the same battle to show the errors :) for now I'm using :

<span class="errors badge badge-important">@elements.errors.mkString(", ")</span>

That would be hidden if there is no error, take a look on this : http://twitter.github.com/bootstrap/components.html#labels-badges

but still looking for a way to translate "Required" to portuguese.