Arsenalist

The Toronto Raptors Blog with an Arsenal touch

Struts 2 Form Control Templates

Posted by Arsenalist on April 11, 2007

This, like many other areas of Struts 2 has remained virtually unchanged after it’s port from Webwork. The idea is that you can template the look of your controls in a fine-grained or application-wide level. Suppose you have a fetish for good practice and want to precede every occurrence of an input tag with a label tag like so:

<label for="firstName">First Name</label>
   <input type="text" name="firstName"
          id="firstName"/>

Although you can write a label tag for every input tag manually to achieve this effect, you can also specify a template to render your <s:textfield> tags to reduce the actual code you write in your JSP or Freemarker page.

Create a template called text.ftl in the folder template/mySimpleTheme and make sure template is in your classpath. Include the following in text.ftl:

<label
<#if parameters.id?exists>
for="${parameters.id?html}" <#t/>
</#if>
>${parameters.label?html}</label>

<#include "/${parameters.templateDir}/simple/text.ftl" />

The include file is pointing to a bare-bones template packaged with Struts which renders a simple <input type=”text”/> with all its attributes. All we’re doing in the additional code is doing a check for the existence of an id being passed in via the textfield tag and printing it in a label tag along with the value of label that is being passed in. Now that we’ve got a template to work with, all that’s left to do is use it. Here’s a way you can apply it to a single textfield:

<s:textfield id="firstName" name="firstName"
                theme="mySimpleTheme"
                label="First Name"/>

The above would render:

<label for="firstName">First Name</label>
   <input type="text" name="firstName"
          id="firstName"/>

The theme=”mySimpleTheme” declaration is telling Struts to look for a template in the mySimpleTheme directory under template (the default template directory). If you want this template to render all textfield elements instead of you specifying theme=”mySimpleTheme” every time, you can modify the struts.ui.theme and struts.ui.templateDir properties in struts.properties which have the default values of xhtml and template, respectively. To take a peek at the built-in templates that Struts provides, you’ll need to dig open struts2-core-2.0.6.jar and look at the template folder. This is probably a good exercise for anybody trying to develop a custom UI using Struts 2.

As mentioned the default theme is xhtml which renders <td>’s, <tr>’s and every thing else that is undesirable in markup. If you want to disable the rendering of anything but the attributes of the tag, you can use the provided “simple” theme as such:

<s:textfield id="firstName" name="firstName"
                theme="simple"
                label="First Name"/>

Alternately you could just set the struts.ui.theme to simple in struts.properties. You can also set the template attribute of each control to point to a different templates directory.

The overall mechanism for controlling appearance is completely different than Struts 1.x and somewhat more complex than it might need to be for many cases. It’s probably abstracted by erring on the side of caution and allowing you the freedom to tweak your templates any which way. Some might argue that there is an extremely tight binding between the display of controls and their functionality (both being controlled by Struts tags) and they would be true.

This is a fairly low-level method of controlling the look of a control and CSS is your best bet when trying to render them properly. Struts does use CSS classes when rendering their built-in themes of xhtml and xhtml_css although the naming might not be to your liking. For example, if you use their xhtml_css theme and use <s:textfield>, you’ll end up having to write CSS classes called wwgrp and wwlbl to control the display of labels and input elements.

One quick note, the xhtml_css theme also generates a very worthless <br/> tag between a label and the control which can throw of your entire look, do get rid of this you’ll have to do a .wwgrp br { display: none; } in your CSS stylesheeet.

This post has moved here.

Advertisements

9 Responses to “Struts 2 Form Control Templates”

  1. Derek said

    I wasn’t able to get .wwgrp br { display: none; } to work in Firefox 2.0 with the css_xhtml theme. How did you get this to work, which browser did you use?

    I’m subscribing ot the comments to this post, so I can get your answer.

  2. arsenalist said

    Try this CSS. It uses “div.wwgrp br” instead of “.wwgrp br” but that shouldn’t make a difference. Maybe it’s one of the other styles that you’re missing.

    This is working fine for me in FF1,2 and IE6,7

    div.wwgrp br {
    display: none;
    }

    div.wwlbl {
    float: left;
    clear: both;
    }

    div.wwctrl {
    float: right;
    }

  3. Derek said

    Thanks for the info. That worked, but it still isn’t up to the quality of the xhtml theme…. I wish it were because I am a fan of css-based layouts, but in this case I may have to leave the form and the form only rendering with the xhtml template

  4. Edson said

    Hello, what happing?

    10:57:43,234 ERROR [FreemarkerTemplateEngine] Could not load template /template/mytheme/text
    10:57:43,234 ERROR [UIBean] error when rendering
    freemarker.core.ParseException: Unexpected end of file reached.

    at freemarker.core.FMParser.generateParseException(FMParser.java:4635)
    at freemarker.core.FMParser.jj_consume_token(FMParser.java:4506)
    at freemarker.core.FMParser.LooseDirectiveEnd(FMParser.java:2302)
    at freemarker.core.FMParser.Include(FMParser.java:1699)
    at freemarker.core.FMParser.FreemarkerDirective(FMParser.java:2344)
    at freemarker.core.FMParser.Content(FMParser.java:2574)
    at freemarker.core.FMParser.OptionalBlock(FMParser.java:2742)
    at freemarker.core.FMParser.Root(FMParser.java:2914)
    at freemarker.template.Template.(Template.java:149)
    at freemarker.cache.TemplateCache.loadTemplate(TemplateCache.java:376)
    at freemarker.cache.TemplateCache.getTemplate(TemplateCache.java:347)
    at freemarker.cache.TemplateCache.getTemplate(TemplateCache.java:229)

    Thank you.

  5. arsenalist said

    An error in your FTL file.

  6. Edson said

    how a could i use select with this example? Has anyone worked with this?
    I try:
    text.ftl :

    for=”${parameters.id?html}”

    >${parameters.label?html}

    jsp:

    but display no values in the list.

    thank you.

  7. Edson said

    how a could i use select with this example? Has anyone worked with this?
    I try:
    text.ftl :


    for=”${parameters.id?html}”

    >${parameters.label?html}

    jsp:

    but display no values in the list.

    thank you.

  8. ebi said

    you’ve just help me resolve an issue i had which was basically to remove the row elements from a textfield tag.

  9. Seb L. said

    Hi,

    It is a very interesting article !

    I would like to know if it is possible to add custom parameter to a template with the <s:param /> tag ? And so, how to get the value of this parameter in the template ?

    Thanks,

Sorry, the comment form is closed at this time.

 
%d bloggers like this: