Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Almost invariably, web applications generate validation errors at some point. And the user has to be told that they did something wrong, and what they should do about it. Hopefully this should be consistent with your applications UI guidelines, and make it clear to the user how to proceed. This how-to explains the tools available in Stripes to help you.

Outputting Errors

Stripes provides a number of tags to output validation errors, and it is worth taking the time to read the tag library documentation for them. The main tag is stripes:errors. This tag can output all the validation errors for a form, or output the errors only for a single field.

I won't repeat the tag documentation here (go read it already!), but here are a couple of examples:

Code Block
xml
languagexml
titleExample 1: Outputting all errors with default formatting
<stripes:errors/> 

The above example will, assuming it is not nested inside a <stripes:form> tag, output all the validation errors in an HTML unordered list, for whatever form was posted. If you have more than one form on the page, you can display the errors for each in different places:

Code Block
xml
languagexml
titleExample 2: Multiple forms outputting errors in different locations
<stripes:form action="/foo/first.action"> 
    <stripes:errors/> 
    ... 
</stripes:form> 

... 

<stripes:errors action="/foo/second.action"> 
<stripes:form action="/foo/second.action"> 
    ... 
</stripes:form> 

...

The next example shows how to ouput errors for a single field at a time, and output global errors (those not associated to any specific field) separately:

Code Block
xml
languagexml
titleExample 3: Outputting errors by field
<stripes:form action="/foo/fist.action"> 
    <stripes:errors globalErrorsOnly="true"/> 

    <table> 
        <tr> 
            <td>Username:</td> 
            <td> 
                <stripes:text name="username"/> 
                <stripes:errors field="username"/> 
            </td> 
        </tr> 
        <tr> 
            <td>Password:</td> 
            <td> 
                <stripes:text name="password"/> 
                <stripes:errors field="password"/> 
            </td> 
        </tr> 
    </table> 
</stripes:form> 

...

It may at first seem a little limiting to have only a single class name for displaying all form fields in error. What if you want to display graphical widgets like selects, check boxes and radio buttons differently from textual widgets like text and textareas? Well, if you asked that question, then it's time to learn a little (more) CSS. CSS selectors allow you to specify styles (with the same name) that select different tags based on all sorts of properties. Probably the most useful in this scenario is the attribute selector. The following shows how to use attribute selectors to apply a global error style to input fields, and then specific changes for some types.

Code Block
languagecss
titleUsing selectors to specify error classes
input.error, textarea.error { 
    color: red; 
    background-color: yellow; 
} 

input.error[type="radio"], input.error[type="checkbox"], select.error { 
    background-color: white; 
    border: 2px solid red; 
} 

...

Let's assume for now that we stick with a single TagErrorRenderer, and that our goal is to ouput a red asterisk next to the field. The first thing we'll need to do is to implement a TagErrorRenderer.

Code Block
languagejava
titleA custom TagErrorRenderer
public class CustomTagErrorRenderer implements TagErrorRenderer { 
    private InputTagSupport tag; 

    /** Store the tag that is in error. */ 
    public void init(InputTagSupport tag) { 
        this.tag = tag; 
    } 

    /** Output our asterisk before the tag/field itself is rendered. */ 
    public void doBeforeStartTag() { 
        try { 
            this.tag.getPageContext().getOut().write 
                ("<span style=\"color:red; font-weight:bold;\">*</span>"); 
        } 
        catch (IOException ioe) { 
            // Not really a whole lot we can do if writing to out fails! 
        } 
    } 

    /** Doesn't need to do anything. */ 
    public void doAfterEndTag() { } 
} 

...

Now that we have our own TagErrorRenderer we have to tell Stripes to use it. The easiest way to do this is to just have it automatically loaded by putting the class in a package that's configured with the Extension.Packages parameter (see Extensions). Alternatively, you can configure the DefaultTagErrorRendererFactory to use the new renderer by using this init-param:

Code Block
xml
languagexml
<init-param> 
    <param-name>TagErrorRenderer.Class</param-name> 
    <param-value>com.myco.web.util.CustomTagErrorRenderer</param-value> 
</init-param> 

...