3

I am in the middle of rewriting a site that was originally written in Weblogic Beehive to JSF 2.0, and I'm running into an issue where I need to get the messages that the new site produces into a format that EXACTLY matches the output of the existing site.

I have tried using the tag which is nice, but the style and logic of the existing messages framework does not fit nicely into this output.

Are there options in JSF that would allow me to create a custom tag that will not only output the messages, but perform conditional logic on them as well?

For example, I have been creating FacesMessages with a summary and detail String, but the format of the old site only displays the highest summary. For example I add 4 messages, each has the same summary message, and different details. I only want to display the summary with the highest severity.

Also, I need the messages displayed and styled as a box, not each message and some of the details need to have conditional CSS classes.

bakoyaro
  • 2,550
  • 3
  • 36
  • 63
  • In future JSF questions, please mention and tag JSF spec version used. Answers usually heavily depends on that. – BalusC Aug 09 '11 at 19:16

2 Answers2

3

If you're using JSF 2.x, then you can iterate over FacesContext#getMessageList() in a loop. Each item is a FacesMessage which in turn has several getters.

<ui:repeat value="#{facesContext.messageList}" var="facesMessage">
    Severity: #{facesMessage.severity}<br />
    Summary: #{facesMessage.summary}<br />
    Detail: #{facesMessage.detail}<br />
    <br />
</ui:repeat>

This allows for more fine-grained HTML markup around the messages.

If you're still on JSF 1.x which lacks this method in FacesContext, then you need to collect FacesContext#getMessages() in a List<FacesMessage> first with help of some utility bean or even an EL function:

List<FacesMessage> messageList = new ArrayList<FacesMessage>();
Iterator<FacesMessage> messages = FacesContext.getCurrentInstance().getMessages();

while (messages.hasNext()) {
    messageList.add(messages.next());
}

You can then iterate over this messageList in your view using <ui:repeat> the same way.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the tip. Iterating over the list isn't so much the issue. I can do that with my eyes closed;-) I want to conditionally display the summary and display un-escaped html in cases where a message has a special style. I'm using JSF 2.0 – bakoyaro Aug 09 '11 at 19:54
  • Just use respectively the JSF `rendered` attribute and the `` component the usual way. As said, you've all freedom to control the markup now. – BalusC Aug 09 '11 at 19:56
  • Thanks for the comment, I appreciate you taking the time to help me out. I'm having some trouble with learning and using JSF, and you are the defacto font of information for JSF at SO. Can you recommend a good JSF 2.0 book to assist me? I'm a senior developer using Eclipse, familiar with JEE, it's just the JSF stuff that I'm having an issue with learning/using. thanks, bakoyaro – bakoyaro Aug 14 '11 at 15:09
0

I ended up with this in my JSF page (xhtml):

            <c:set var="messageList" value="#{facesContext.messageList}" />
            <c:set var="maxSev" value="#{facesContext.maximumSeverity.ordinal}" />
            <ui:repeat value="${messageList}" var="fm" >
                <c:choose>
                     <c:when test="${fm.severity.ordinal eq 0}">
                         <c:set var="summaryStyleClass" value="outcome"/>
                         <c:set var="detailStyleClass" value="outcome_details"/>
                     </c:when>
                     <c:when test="${fm.severity.ordinal eq 1}">
                         <c:set var="summaryStyleClass" value="warning_title"/>
                         <c:set var="detailStyleClass" value="warning"/>
                     </c:when>
                     <c:when test="${fm.severity.ordinal eq 2}">
                         <c:set var="summaryStyleClass" value="error_title"/>
                         <c:set var="detailStyleClass" value="error"/>
                     </c:when>
                     <c:when test="${fm.severity.ordinal eq 3}">
                         <c:set var="summaryStyleClass" value="fatal"/>
                         <c:set var="detailStyleClass" value="fatal_details"/>
                     </c:when>
                </c:choose>
            </ui:repeat>
            <div class="${detailStyleClass}" >
                 <div class="${summaryStyleClass}">
                        <ui:repeat value="${messageList}" var="fm" >
                             <c:choose>
                                 <c:when test="${fm.severity.ordinal eq maxSev}">
                                     ${fm.summary}
                                 </c:when>
                             </c:choose>
                        </ui:repeat>
                 </div>
                  <ul>
                     <ui:repeat value="${messageList}" var="msg">
                         <li><h:outputText value="${msg.detail}"/></li>
                     </ui:repeat>
                </ul>
            </div>

I'm sure I'm breaking a pattern here, but the section doesn't seem to be working where it can resolve summaryStyleClass and detailStyleClass vars. I'm iterating through them because I need to style the message depending on what the highest severity message is for the page. This is the rendered output that I'm getting in the page in the browser:

            <div>
                 <div>Warning:</div>
                 <ul>
                      <li>Warning message.</li>
                </ul>
            </div>

Notice no styles...

bakoyaro
  • 2,550
  • 3
  • 36
  • 63