【问题标题】:JSF - How can I format my global messages in <h:messages> in a visually appealing way?JSF - 如何以视觉上吸引人的方式格式化 <h:messages> 中的全局消息?
【发布时间】:2010-09-14 13:09:30
【问题描述】:

我不太熟悉在 JSF 中使用 &lt;h:messages&gt; 元素。我想要做的是使用它来显示由我的支持 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...

一切正常。我的问题是试图使&lt;h:messages&gt; 标签的输出在页面上看起来不错。这是我的 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"。我将&lt;h:messages&gt; 框在&lt;h:panelGrid&gt; 中,这样我就有了一些可以应用样式的块级元素。看起来还是不是特别好看。

我现在得到的:

<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 类
  • 消息的“摘要”和“详细信息”部分具有不同的样式类
  • 很高兴:表格标题行

屏幕截图:

有没有人使用&lt;h:messages&gt; 标签并对我如何实现这一点有一些想法?

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

【问题讨论】:

  • 这是 CSS 的问题。您的实际问题可能只是 CSS 技能不佳。在不知道它的外观的情况下,很难给出答案。请张贴一些图片/屏幕截图,说明它应该(不)是什么样子。
  • @BalusC 没错,我不是 CSS 专家。我将尝试模拟一些 HTML 来说明我的问题并将其附加到问题中。我没有任何地方可以托管屏幕截图。
  • 您可以在这里上传图片。单击消息编辑器工具栏中的图像按钮以选择本地图像文件。
  • @BalusC 完成。我以前从未注意到截图上传按钮。

标签: java css web-applications jsf myfaces


【解决方案1】:

毕竟,您想更改 HTML 输出。这真的不能用CSS来完成。 CSS 更多的是给现有的 HTML 元素一个布局,而不是修改它们。除了在 JavaScript 中摆弄(在这种特殊情况下这并不容易),您还希望 JSF 更改其 HTML 输出。基本上有两种方式:

  1. 提供您自己的MessagesRenderer,以便它以您想要的方式呈现消息。扩展在 MyFaces 中使用的基本渲染器类(抱歉,因为我不使用 MyFaces,所以我无法从头顶判断它是用于 MyFaces 的哪个类,您需要查阅它的 API 文档)并在 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>
    

    在这里,com.example.CustomMessagesRenderer 是您实现的自定义渲染器。您想覆盖标准渲染器的 encodeEnd() 方法,让它以所需的方式输出 HTML。代码太多,无法在此处作为示例发布,但仅查看默认消息渲染器的源代码即可提供足够的提示。

  2. FacesContext#getMessages() 的帮助下收集List&lt;FacesMessage&gt; 中的消息,并在c:forEacht:dataList 和普通的HTML 的帮助下显示它们。例如

    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;
    }
    

    <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>
    

    在 JSF2 中,您应该直接使用 #{facesContext.messageList} 而不是 #{bean.messages}

【讨论】:

  • 谢谢。我需要一些时间来试验这个。
  • 不客气。您基本上可以从原始源代码中复制粘贴整个方法,并在必要时进行修改。祝你好运:)
  • @Hendy:谢谢。请注意,此答案针对 JSF 1.x。对于 JSF 2.x,有更简洁的方法。
  • 很好的答案。但是,老实说,显示摘要和细节的 JSF 实现是相当不灵活的。如果它们默认打印在同一行文本中,为什么要区分它们?没有意义。消息组件至少应该有一些东西可以应用不同的样式。
【解决方案2】:

正如 BalusC 所说,这是 CSS 技能的问题。不过,我有一个实用的建议:

  • 打开页面
  • 见“查看源代码”
  • 复制生成的文件并尝试将您的 css 技能应用于生成的 HTML。
  • 或者,使用 FireBug 并动态添加样式并检查其外观。

【讨论】:

    猜你喜欢
    • 2013-11-01
    • 2013-12-07
    • 2012-06-17
    • 1970-01-01
    • 2012-11-17
    • 2012-05-16
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    相关资源
    最近更新 更多