How do I enforce the order which error messages are displayed when using validation annotations?

249 views Asked by At

I have the below model, view and error messages.

Model

public class LoginModel {
    @Required(message = "validation.required.email")
    public String email;

    @Required(message = "validation.required.password")
    public String password;
}

View

@for((field, validationErrors) <- myForm.errors) {
    @for(validationError <- validationErrors) {
        <li>@Messages(validationError.message)</li>
    }
}

conf/messages

error.no_email=You must enter an email
error.no_password=You must enter a password

The message "You must enter a password" appears before the "You must enter an email". I would like them in the same order I have them on my form (which is email followed by password). Is there a way to define the order which error messages are displayed when errors are added automatically by play from validation annotations?

3

There are 3 answers

0
David Spence On BEST ANSWER

It's a bit of an overheard (and I don't like the solution) but it's possible via:

@for(error <- form("email").errors) {
    <li>@Messages(error.message)</li>
}

@for(error <- form("password").errors) {
    <li>@Messages(error.message)</li>
}

It still means that the order of the messages are not guaranteed for each field, but at least you can enforce the order at a field level so they can match up to the order of the fields on your form.

4
Mon Calamari On

Play Form internally uses HashMap for storing validation errors, thus order is not enforced. You can grab the sources from github, extend the form and replace HashMap occurrences with LinkedHashMap.

3
jschnasse On

In play 2.6.0 the method allErrors() has been introduced. It returns an unmodifiableList of all errors.

This allows one to ...

1. ... implement public List<ValidationError> validate() at the model class like described here

2. ... retrieve the ordered list later in the controller when testing if form.hasErrors().

This wasn't possible in versions before play 2.6, because the errors were stored in a map. Since play 2.6 form errors are stored in a list and errors() has been marked as deprecated.