Over a million developers have joined DZone.

Replacement for s:decorate in Seam 3

DZone's Guide to

Replacement for s:decorate in Seam 3

· Java Zone ·
Free Resource

Get the Edge with a Professional Java IDE. 30-day free trial.

I've been doing a gap analysis for our migration from Seam 2 to Seam 3, and I was dismayed to find that the <s:decorate> tag is gone! In Seam 2, you create a template like this:

<ui:composition  xmlns="http://www.w3.org/1999/xhtml"

    <div class="prop">
        <s:label styleClass="nameEdit #{invalid?'errors':''}">
            <s:span styleClass="required"
            <ui:insert name="label"/>

        <span class="value #{invalid?'errors':''}">

        <span class="error">
            <h:graphicImage value="/img/error.gif" 
                rendered="#{invalid}" styleClass="errors"/>

And then reference it using <s:decorate>

<s:decorate template="edit.xhtml">
  <ui:define name="label">Country:</ui:define>
  <h:inputText value="#{location.country}" required="true"/>

And now required fields are noted with an asterisk (*), all fields are automatically validated, and when they have errors, a special style is applied and the error message appears to the right of the field:

Note: this is all documented in Section 33.1.13 of the Seam 2 reference.

Pretty slick! I definitely need this functionality when I migrate to Seam 3, but the <s:decorate> tag is gone, and I had a hard time finding a replacement.

Replacing with UIInputContainer

Fortunately, a close replacement actually exists in Seam 3's Faces module... it just isn't described as such! Seam Faces provides a component called UIInputContainer. When this is combined with a JSF 2 composite component, you can get the same functionality.

First, create your composite component. I created mine at WebContent/resources/orr/decorate.xhtml:

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<html xmlns="http://www.w3.org/1999/xhtml"

<composite:interface componentType="org.jboss.seam.faces.InputContainer" />

  <h:outputLabel id="label" value="#{cc.attrs.label}:"
   styleClass="#{cc.attrs.invalid ? 'invalid' : ''}">

   <h:outputText styleClass="required" rendered="#{cc.attrs.required}"
    value="*" />


  <!-- h:panelGroup is a workaround for a JSF bug, see http://java.net/jira/browse/JAVASERVERFACES-1991  -->
  <h:panelGroup styleClass="value #{invalid?'errors':''}" >
   <composite:insertChildren />

  <h:message id="message" errorClass="invalid message"
   rendered="#{cc.attrs.invalid}" />

Since I put the composite component in WebContent/resources/orr/decorate.xhtml, the namespace is http://java.sun.com/jsf/composite/orr and the tag name is decorate.

Now use this new tag in your Facelets page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"

<o:decorate label="Country:">
    <h:inputText value="#{location.country}" required="true"/>

And that's it! This will generate roughly the same output and behavior as Seam 2's <s:decorate> tag. So all along, there was a pretty good replacement, but either this wasn't made clear anywhere, or my Google skills aren't quite as good as I think. I imagine this would be documented in JBoss's Seam 2 to Seam 3 migration guide, if such a thing existed...





Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}