Global messages in popup using Richfaces

Goal

Show global user messages in a popup, when using Richfaces 3.3.x

Description

This recipe explains how to show global messages in JSF when using Richfaces 3.3.x. It uses only richfaces components and some javascript. In Richfaces 4, there already is a component that shows messages as a popup (namely, the rich:notify component). However, no equivalent component exists in richfaces 3.

So, lets see how to create a global message panel in a popup by using only a richfaces modal panel and some javascript to automatically hide that popup, a few seconds after being shown.

How to

First, we will set our global messages component inside a modal panel as shown in the following snippet. That code could be included in our application’s main layout file so that pages in our application would benefit from this feature.

<rich:modalPanel id="messagesPanel"
  showWhenRendered="#{not empty facesContext.maximumSeverity}"
  onshow="autoHideMessagePanel()" top="0" autosized="false"
  width="250" height="100" left="5" resizeable="false"
  moveable="false" shadowOpacity="0">
      <f:facet name="header">#{messages['label.messages.title']}</f:facet>
      <f:facet name="controls">
          <h:panelGroup>
              <h:graphicImage value="/img/icons/close.png" 
                onclick="Richfaces.hideModalPanel('messagesPanel');" 
              />
          </h:panelGroup>
      </f:facet>
      <rich:messages id="messages" globalOnly="true" styleClass="message"
        errorClass="errormsg" infoClass="infomsg" warnClass="warnmsg" 
      />
</rich:modalPanel>

The trick consist on the following definitions:

  • showWhenRendered – this property is defined as being presented only when there are any messages in context, as specified by the EL "{not empty facesContext.maximumSeverity}
  • onshow – a javascript function that will set a timeout on the popup window when shown so that it automatically hides after a specified elapsed time
  • globalOnly – the property set in the messages component that causes it to be shown only when the context messages are global, i.e., not associated to any particular JSF component

And to complete the recipe, here is the piece of javascript that takes the extra mile, i.e., that automatically hides the popup panel, after the message is shown (2 seconds, in the snippet below):

var messagesDialogTimer = 2000;
function autoHideMessagePanel() {
    setTimeout(function() { 
        Richfaces.hideModalPanel('messagesPanel'); 
    }, messagesDialogTimer);
}

Although simple and useful, the previous code sample still has some problems, namely the situation where there are non global messages, because the popup will show up with no messages inside! To fix this problem, we need to make the panel aware of that fact. To do so, we could follow the approach of creating an EL function, as explained here or you could define a named component (if you are using seam, for instance) that contains the function that checks for global messages as follows:

@Name("elFunctions")
public class ELFunctions {

    public boolean isGlobal() {
        return FacesContext.getCurrentInstance().getMessages(null).hasNext();
    }
}

and the corresponding change in the modal panel definition, in the attribute showWhenRendered, so that, instead of #{not empty facesContext.maximumSeverity}, you specify #{elFunctions.global}.

Explanations

This recipe has enabled us to get pretty global messages in a popup window without breaking our application (we had a solution based on jquery which was causing us some javascript incompatibility problems due to different versions being used by richfaces and the solution that was implemented to show the messages in a popup). It is simple, functional and keeps us on the safe side. Therefore, I recommend its usage when the technology at hand is richfaces 3.3.3

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s