How do I write and configure a custom facelet to override h:messages?
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.
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.
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...
链接地址: http://www.djcxy.com/p/71656.html