How can I show a validation error for a form field outside of a field constructor in Play framework 2? Here is what I tried:
@eventForm.("name").error.message
And I get this error:
value message is not a member of Option[play.api.data.FormError]
I'm confused because in the api docs it says message is a member of FormError. Also this works fine for global errors:
@eventForm.globalError.message
You can get a better grasp of it checking Form's sourcecode here
Form
defines an apply method:
def apply(key: String): Field = Field(
this,
key,
constraints.get(key).getOrElse(Nil),
formats.get(key),
errors.collect { case e if e.key == key => e },
data.get(key))
That, as said in the doc, returns any field, even if it doesn't exist. And a Field
has an errors
member which returns a Seq[FormError]
:
So, you could do something like that (for the Seq[FormError]
):
eventForm("name").errors.foreach { error =>
<div>@error.message</div>
}
Or (for the Option[FormError]
)
eventForm("name").error.map { error =>
<div>@error.message</div>
}
Or, you could use Form
errors
:
def errors(key: String): Seq[FormError] = errors.filter(_.key == key)
And get all errors of a given key. Like this (for the Seq[FormError]
):
eventForm.errors("name").foreach { error =>
<div>@error.message</div>
}
Or (for the Option[FormError]
)
eventForm.error("name").map { error =>
<div>@error.message</div>
}
If you want more details, check the source code. It's well written and well commented.
Cheers!
EDIT:
As biesior commented: to show human readable pretty messages with different languages you have to check how play works I18N out here
To be thorough you're probably going to have to deal with I18N. It's not hard at all to get it all working.
After reading the documentation you may still find yourself a bit consufed. I'll give you a little push. Add a messages
file to your conf
folder and you can copy its content from here. That way you'll have more control over the default messages. Now, in your view, you should be able to do something like that:
eventForm.errors("name").foreach { error =>
<div>@Messages(error.message, error.args: _*)</div>
}
For instance, if error.message
were error.invalid
it would show the message previously defined in the conf/messages
file Invalid value
. args
define some arguments that your error message may handle. For instance, if you were handling an error.min
, an arg
could be the minimum value required. In your message you just have to follow the {n}
pattern, where n is the order of your argument.
Of course, you're able to define your own messages like that:
error.futureBirthday=Are you sure you're born in the future? Oowww hay, we got ourselves a time traveler!
And in your controller you could check your form like that (just one line of code to show you the feeling of it)
"year" -> number.verifying("error.furtureBirthday", number <= 2012) // 2012 being the current year
If you want to play around with languages, just follow the documentation.
Cheers, again!
As you said yourself, message
is a member of FormError
, but you have an Option[FormError]
. You could use
eventForm("name").error.map(_.message).getOrElse("")
That gives you the message, if there is an error, and ""
if there isn't.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With