JSF - 如何以视觉上吸引人的方式在<h:messages>中格式化我的全局消息?</h:messages>

时间:2010-09-14 13:09:30

标签: java css web-applications jsf myfaces

我不太熟悉在JSF中使用<h:messages>元素。我正在尝试做的是使用它来显示由我的支持bean中的方法生成的不同严重性的全局消息列表。将消息放入FacesContext并不是一个太大的问题,我的代码就是这样:

FacesMessage message;
FacesContext context = 
    FacesContext.getCurrentInstance();
message = new FacesMessage(
    FacesMessage.SEVERITY_INFO,
    "test message summary 1",
    "test message detail 1");
context.addMessage(null, message);
message = new FacesMessage(
    FacesMessage.SEVERITY_WARN,
    "test message summary 2",
    "test message detail 2");
context.addMessage(null, message);
message = new FacesMessage(
    FacesMessage.SEVERITY_ERROR,
    "test message summary 3",
    "test message detail 3");
context.addMessage(null, message);
// add more messages...

一切正常。我的问题是尝试使<h:messages>标记的输出在页面上看起来很好。这是我的JSP文件的相关部分:

<h:panelGrid border="1" columns="1" id="messagesPanelGrid">
    <h:messages 
        id="messagesOutput"
        showSummary="true"
        showDetail="true" 
        layout="table"
        infoClass="info-message"
        warnClass="warn-message"
        errorClass="error-message"
        fatalClass="fatal-message" 
        globalOnly="true" />
</h:panelGrid>

这一直看起来像页面上的垃圾。我正在使用外部CSS样式表来定义样式类。我已经尝试使用layout="list",但是列表项跨越了整个页面并使任何块样式看起来很糟糕,所以我切换到layout="table"。我在<h:messages>内构建<h:panelGrid>所以我会有一些块级元素可以应用样式。它看起来仍然不是特别好。

我现在得到的是什么:

<table border="1" id="myForm:messagesOutput">
    <tr><td class="error-message"><span>no port name match Could not match reported port name XXXX to a known port for vessel VESSEL A</span></td></tr>
    <tr><td class="error-message"><span>no port name match Could not match reported port name YYYY to a known port for vessel VESSEL B</span></td></tr>
    <tr><td class="error-message"><span>no port name match Could not match reported port name YYYY to a known port for vessel VESSEL C</span></td></tr>
    <tr><td class="error-message"><span>no port name match Could not match reported port name ZZZZ to a known port for vessel VESSEL D</span></td></tr>
    <tr><td class="warn-message"><span>arrival date missing No arrival date provided for vessel VESSEL B</span></td></tr>
</table>

我想要的是:

<table border="1" id="myForm:messagesOutput" class="myMessagesTableClass">
    <thead><tr"><td>SUMMARY</td><td>DETAIL</td></tr></thead>
    <tr><td class="error-message-summary"><span>no port name match</span></td><td class="error-message-detail"><span>Could not match reported port name XXXX to a known port for vessel VESSEL A</span></td></tr>
    <tr><td class="error-message-summary"><span>no port name match</span></td><td class="error-message-detail"><span>Could not match reported port name YYYY to a known port for vessel VESSEL B</span></td></tr>
    <tr><td class="error-message-summary"><span>no port name match</span></td><td class="error-message-detail"><span>Could not match reported port name YYYY to a known port for vessel VESSEL C</span></td></tr>
    <tr><td class="error-message-summary"><span>no port name match</span></td><td class="error-message-detail"><span>Could not match reported port name ZZZZ to a known port for vessel VESSEL D</span></td></tr>
    <tr><td class="warn-message-summary"><span>arrival date missing</span></td><td class="warn-message-detail"><span>No arrival date provided for vessel VESSEL B</span></td></tr>
</table>
        
  • 邮件仍在表格布局中,但“摘要”和“详细信息”位于不同的列中
  •     
  • 生成的表有一个直接分配给它的CSS类
  •     
  • 邮件的“摘要”和“详细信息”部分具有单独的样式类
  •     
  • NICE TO HAVE:表标题行

截图:
alt text

是否有人使用<h:messages>标签并对如何实现此目标有一些想法?

我不确定这个问题是否重要,但我正在使用MyFaces 1.2。我目前无法升级到2.x.

2 个答案:

答案 0 :(得分:7)

毕竟,您想要更改HTML输出。这真的无法用CSS完成。 CSS更多的是为现有HTML元素提供布局,而不是修改它们。除了摆弄JavaScript(在这种特殊情况下这并不容易),你想让JSF改变它的HTML输出。基本上有两种方式:

  1. 提供您自己的MessagesRenderer,以便按照您想要的方式呈现邮件。扩展MyFaces中使用的基础渲染器类(对不起,因为我不使用MyFaces,我无法从头顶看出它是哪个类用于MyFaces,你需要查阅它的API文档)并在{{1中注册它如下:

    faces-config

    因此,<render-kit> <renderer> <component-family>javax.faces.Messages</component-family> <renderer-type>javax.faces.Messages</renderer-type> <renderer-class>com.example.CustomMessagesRenderer</renderer-class> </renderer> </render-kit> 是您实现的自定义渲染器。您希望覆盖标准渲染器的encodeEnd()方法,以使其以所需方式输出HTML。这里有太多代码要发布作为示例,但只要查看默认消息渲染器的源代码就应该给出足够的提示。

  2. FacesContext#getMessages()的帮助下,在com.example.CustomMessagesRenderer的帮助下收集邮件,并在List<FacesMessage>c:forEach以及普通的HTML语言的帮助下显示这些消息。 E.g。

    t:dataList

    public List<FacesMessage> getMessages() {
        List<FacesMessage> messages = new ArrayList<FacesMessage>();
        Iterator<FacesMessage> iter = FacesContext.getCurrentInstance().getMessages();
        while (iter.hasNext()) {
            messages.add(iter.next());
        }
        return messages;
    }
    

    在JSF2中,您已直接使用#{facesContext.messageList}而不是<table border="1" id="myForm:messagesOutput" class="myMessagesTableClass"> <thead><tr><td>SUMMARY</td><td>DETAIL</td></tr></thead> <tbody> <c:forEach items="#{bean.messages}" var="message"> <c:set var="type" value="#{message.severity == 'SEVERITY_ERROR' ? 'error' : 'warn'}" /> <tr> <td class="#{type}-message-summary"><span>#{message.summary}</span></td> <td class="#{type}-message-detail"><span>#{message.detail}</span></td> </tr> </c:forEach> </tbody> </table>

答案 1 :(得分:2)

正如BalusC评论的那样,这是CSS技能的问题。但是,我有一个实用的建议:

  • 打开页面
  • 请参阅“查看来源”
  • 复制生成的文件,然后尝试将css技能应用于生成的HTML。
  • 或者,使用FireBug并动态添加样式并检查它的外观。