4

私は<h:messages>JSF で要素を使用することにあまり慣れていません。私がやろうとしているのは、それを使用して、バッキング 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 クラスがあります
  • メッセージの「要約」部分と「詳細」部分には、別々のスタイル クラスがあります。
  • あると便利: テーブルのヘッダー行

スクリーンショット:
代替テキスト

誰かが<h:messages>タグを扱っていて、これを達成する方法についていくつかのアイデアを持っていますか?

この質問に関係があるかどうかはわかりませんが、MyFaces 1.2 を使用しています。現時点では 2.x にアップグレードできません。

4

2 に答える 2

8

結局のところ、HTML 出力を変更する必要があります。これは実際には CSS では実現できません。CSS は、既存の HTML 要素にレイアウトを与えるためのものであり、変更するためのものではありません。JavaScript をいじる (この特定のケースでは簡単ではありません) ことは別として、JSF に HTML 出力を変更させたいと考えています。基本的に次の 2 つの方法があります。

  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. List<FacesMessage>の助けを借りてメッセージを収集し、単純なバニラ HTMLFacesContext#getMessages()の助けを借りてそれらを表示します。例えばc:forEacht: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;
    }
    

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

于 2010-09-14T14:35:10.357 に答える
2

BalusC がコメントしたように、これは CSS のスキルの問題です。ただし、実用的なアドバイスが 1 つあります。

  • ページを開く
  • 「ソースを表示」を参照
  • 結果のファイルをコピーして、生成された HTML に CSS スキルを適用してみてください。
  • または、FireBug を使用してスタイルを動的に追加し、それがどのように見えるかを確認します。
于 2010-09-14T13:17:10.393 に答える