• cdi
  • components
  • contexts
  • converters
  • eventlisteners
  • exceptionhandlers
  • facesviews
  • filters
  • functions
  • managedbeans
  • push
  • renderkits
  • resourcehandlers
  • scripts
  • servlets
  • taghandlers
  • utils
  • validators
  • viewhandlers
-
  • cache
  • commandScript
  • componentIdParam
  • conditionalComment
  • deferredScript
  • form
  • graphicImage
  • highlight
  • messages
  • moveComponent
  • onloadScript
  • outputFormat
  • outputLabel
  • param
  • resolveComponent
  • resourceInclude
  • tree
  • viewAction
  • viewParam

The <o:messages> is a component that extends the standard <h:messages> with the following new features:

Multiple for components

Possibility to specify multiple client IDs space separated in the for attribute. The example below would only display messages for input1 and input3:

<h:form>
    <o:messages for="input1 input3" />
    <h:inputText id="input1" />
    <h:inputText id="input2" />
    <h:inputText id="input3" />
    <h:inputText id="input4" />
</h:form>

It can even refer non-input components which in turn contains input components. The example below would only display messages for input1 and input2:

<h:form>
    <o:messages for="inputs" />
    <h:panelGroup id="inputs">
        <h:inputText id="input1" />
        <h:inputText id="input2" />
    </h:panelGroup>
    <h:inputText id="input3" />
    <h:inputText id="input4" />
</h:form>

You can even combine them. The example below would only display messages for input1, input2 and input4.

<h:form>
    <o:messages for="inputs input4" />
    <h:panelGroup id="inputs">
        <h:inputText id="input1" />
        <h:inputText id="input2" />
    </h:panelGroup>
    <h:inputText id="input3" />
    <h:inputText id="input4" />
</h:form>

Displaying single message

Show a single custom message whenever the component has received any faces message. This is particularly useful when you want to display a global message in case any of the in for specified components has a faces message. For example:

<o:messages for="form" message="There are validation errors. Please fix them." />
<h:form id="form">
    <h:inputText id="input1" /><h:message for="input1" />
    <h:inputText id="input2" /><h:message for="input2" />
    <h:inputText id="input3" /><h:message for="input3" />
</h:form>

HTML escaping

Control HTML escaping by the new escape attribute.

<o:messages escape="false" />

Beware of potential XSS attack holes when user-controlled input is redisplayed through messages!

Iteration markup control

Control iteration markup fully by the new var attribute which sets the current FacesMessage in the request scope and disables the default table/list rendering. For example,

<dl>
    <o:messages var="message">
        <dt>#{message.severity}</dt>
        <dd title="#{message.detail}">#{message.summary}</dd>
    </o:messages>
</dl>

Note: the iteration is by design completely stateless. It's therefore not recommended to nest form components inside the <o:messages> component. It should be used for pure output only, like as the standard <h:messages>. Plain output links are however no problem. Also note that the message and escape attributes have in this case no effect. With a single message, there's no point of iteration. As to escaping, just use <h:outputText escape="false"> the usual way.

Design notice

The component class is named OmniMessages instead of Messages to avoid confusion with the Messages utility class.

Demo

Multiple for components

Register one messages component for multiple input components.

Register one messages component for a specific group containing multiple input components.


Displaying single message

Show a single custom message whenever the component has received any faces message. Leave the inputs empty to see it.

Control HTML escaping

Default HTML escaping can be turned off by the new escape attribute.

Control iteration markup

Control iteration markup fully by the new var attribute which sets the current FacesMessage in the request scope and disables the default table/list rendering.

Admittedly, this was a bit poor example. The same layout could also be achieved with just <o:messages> without var attribute. It's just to give the general idea.

Demo source code
<h3>Multiple <code>for</code> components</h3>
<p>
    Register one messages component for multiple input components.
</p>
<h:form id="form1">
    <o:messages for="input1 input2" />
    <h:panelGrid>
        <h:inputText id="input1" required="true" />
        <h:inputText id="input2" required="true" />
        <h:panelGroup>
            <h:inputText id="input3" required="true" />
            <h:message for="input3" />
        </h:panelGroup>
        <h:commandButton value="Submit">
            <f:ajax execute="@form" render="@form" />
        </h:commandButton>
    </h:panelGrid>
</h:form>
<p>
    Register one messages component for a specific group containing multiple input components.
</p>
<h:form id="form2">
    <o:messages for="inputs" />
    <h:panelGrid>
        <h:panelGroup id="inputs">
            <h:inputText id="input1" required="true" />
            <br/>
            <h:inputText id="input2" required="true" />
        </h:panelGroup>
        <h:panelGroup>
            <h:inputText id="input3" required="true" />
            <h:message for="input3" />
        </h:panelGroup>
        <h:commandButton value="Submit">
            <f:ajax execute="@form" render="@form" />
        </h:commandButton>
    </h:panelGrid>
</h:form>

<h3>Displaying single message</h3>
<p>
    Show a single custom message whenever the component has received any faces message.
    Leave the inputs empty to see it.
</p>
<h:form id="form3">
    <o:messages for="form3" message="There are validation errors. Please fix them." />
    <h:panelGrid columns="2">
        <h:inputText id="input1" required="true" />
        <h:message for="input1" />
        <h:inputText id="input2" required="true" />
        <h:message for="input2" />
        <h:inputText id="input3" required="true" />
        <h:message for="input3" />
        <h:commandButton value="Submit">
            <f:ajax execute="@form" render="@form" />
        </h:commandButton>
        <h:panelGroup />
    </h:panelGrid>
</h:form>

<h3>Control HTML escaping</h3>
<p>
    Default HTML escaping can be turned off by the new <code>escape</code> attribute.
</p>
<h:form id="form4">
    <o:messages escape="false" />
    <h:commandButton value="Show HTML message" action="#{messagesBean.showHtmlMessage}">
        <f:ajax execute="@form" render="@form" />
    </h:commandButton>
</h:form>

<h3>Control iteration markup</h3>
<p>
    Control iteration markup fully by the new <code>var</code> attribute which sets the current 
    <code>FacesMessage</code> in the request scope and disables the default table/list rendering.
</p>
<h:form id="form5">
    <ui:fragment rendered="#{not empty facesContext.messageList}">
        <ul class="messages">
            <o:messages var="message">
                <li class="#{fn:toLowerCase(message.severity)}">#{message.summary}</li>
            </o:messages>
        </ul>
    </ui:fragment>
    <h:commandButton value="Show five random messages" action="#{messagesBean.showRandomMessages(5)}">
        <f:ajax execute="@form" render="@form" />
    </h:commandButton>
</h:form>
<p>
    Admittedly, this was a bit poor example. The same layout could also be achieved with just 
    <code>&lt;o:messages&gt;</code> without <code>var</code> attribute.
    It's just to give the general idea.
</p>