0

次の問題を解決するのに苦労しています。私の問題は非常に単純です。検証エラーを引き起こしたフォームフィールドを赤で強調表示したいと思います。エラーメッセージは、context.addMessage(...)行を使用してFacesContextに正しく配置されます。

システムを汎用的にしたいと思います。メッセージが添付されているすべてのフォームフィールドが自動的に強調表示されます。

私はこのサイトでこの優れた記事へのリンクを見つけました: http ://www.jroller.com/mert/entry/how_to_find_a_uicomponent

これを使用して、RENDER_RESPONSEフェーズのPhaseListenerを実装しました。これは、次のことを行います。

@Override
  public void beforePhase(PhaseEvent event) {
    // get context
    FacesContext context = event.getFacesContext();

    // iterate on all the clientIds which have messages
    Iterator<String> clientIdsWithMessages = context.getClientIdsWithMessages();
    while (clientIdsWithMessages.hasNext()) {

      // get the clientId for the field component
      String clientIdWithMessage = clientIdsWithMessages.next();
      // split on ":"
      String[] splitted = clientIdWithMessage.split(":");

      UIComponent component = findComponentInRoot(splitted[splitted.length - 1]);
      if (component != null) {
        Map<String, Object> attributes = component.getAttributes();

        if (attributes.containsKey("style")) {
          attributes.remove("style");
        }
        attributes.put("style", "background-color: #FFE1E1;");
      }
    }
  }

これは、ほとんどすべての使用法で完全に機能します。

さて、それが少しトリッキーになるところは、私のフォームのいくつかがそのようなコードを持っているということです:

<ice:dataTable id="revisionDocuments" value="#{agendaBean.agenda.revisionsDocuments}" var="revision">
    <ice:column>
        <ice:inputText value="#{revision.sequenceAdresse}" id="revisionSequenceAdresse" />
    </ice:column>
    ....

生成されたフォームには複数の行があり(revisionsDocumentsリストのオブジェクトごとに1つ)、各要素には次のような一意の識別子(clientId)があります。

contentForm:revisionDocuments:0:revisionSequenceAdresse

反復ごとに1、2、...の0が変更されます。その結果、ViewRootからUIComponentを検索するために提供されたコードは正しく機能しません。すべてのフォームフィールドには同じ「id」があります。さらに驚いたのは、FacesContextにも同じ「clientId」があることです。

contentForm:revisionDocuments:revisionSequenceAdresse

ツリーを調べている間、正しいフォームフィールドまたは他のフィールドが表示されているかどうかを区別できません。

誰かがこれを解決するためのヒントを持っていますか?または私のフィールドのハイライトを実装するための別の提案?私は認めなければなりません、私は自分のコードが本当に好きではありません、私がしているようにviewRootを操作するのは汚いと思いますが、私のフィールドの一般的なハイライトを持つためのより良い解決策を見つけることができませんでした。

JBOssAS7.0.2.FinalでJSF-Impl2.1.1-b04を使用してIceFaces2.0.2を実行しています。

よろしくお願いします。よろしく、パトリック

4

2 に答える 2

2

代わりに、これをクライアント側で適用する必要があります。メッセージ付きのクライアントIDのコレクションがあります。方法の1つは、この情報をJavaScriptに渡して、JavaScriptに処理させることです。PhaseListenerこの記事でそのような例を見つけることができます: JSFでフォーカスとハイライトを設定します

ただし、JSF 2.0以降、を必要としない別の方法がありPhaseListenerます。現在のコンポーネントのインスタンス#{component}を参照する新しい暗黙のEL変数があります。コンポーネントのUIComponent場合、メソッドがあります。これにより、次のようなことができます。UIInputisValid()

<h:inputText styleClass="#{component.valid ? '' : 'error'}" />

これをCSSファイルに入れます:

.error {
    background: #ffe1e1;
}

(はい、style属性でこれを行うこともできますが、マークアップとスタイルを混ぜることはお勧めできません)

これを抽象化するには(すべての入力で繰り返す必要がないように)、このための複合コンポーネント<my:input>を作成するだけです。

于 2011-12-09T13:32:42.743 に答える
0

完全を期すために、IceFaces2.0.2でエラーメッセージが表示されるフィールドを強調表示するために最終的に見つけた解決策を次に示します。

基本的な考え方は、 http: //balusc.blogspot.com/2007/12/set-focus-in-jsf.htmlでBalusCによって提案されたものと厳密に同じです。

IceFacesで変更しなければならなかったコードは、小さなJavascript呼び出しです。

<script>
    setHighlight('${highlight}');
</script>

JS呼び出しごとに再レンダリングされるIceFacesコンポーネントが見つかりませんでした。スクリプトをpanelGroupに配置すると、ほとんどの場合機能することがわかりました。しかし、うまくいかなかったケースがありました:

エラーのあるフォームを送信すると、JSがトリガーされます。次に、以前の検証と同じフィールドにエラーがあるフォームを再送信しても、JSはトリガーされません。次に、エラーがなくなったエラーフィールドを使用してフォームを再送信すると、JSがトリガーされます。次に、エラーのあるエラーのないフィールドを使用してフォームを再送信すると、JSがトリガーされます。

何らかの理由で、エラーのあるフィールドのセットが2つの呼び出し間で同じである場合、IceFacesはJSを含むpanelGroupをレンダリングしません。

プロトタイプライブラリを使用してcommandButtonのAJAX完了にイベントをアタッチし、Ice.onAsynchronousReceive()などのコードでJavascript APIを使用しようとしましたが、あまり成功しませんでした。私のテストのいくつかは実行でき(エラーはありましたが、仕事はしました)、同様の動作を観察できました。

これが私が最終的に使用したトリックです(醜いですが機能しています):

<ice:panelGroup>
    <script type="text/javascript">
        var useless = '#{testBean.time}';
        setHighlight('${highlight}');
    </script>
</ice:panelGroup>

getTime()関数は、単に現在のタイムスタンプを返します。その場合、値は常に異なり、AJAXリクエストでJSの実行をトリガーします。

残念ながら、IceFacesにはRichFacesの有用な「oncomplete」属性がありません。この場合は非常に残念です。

醜い解決策ですが、面白くて機能しています。

于 2011-12-16T08:57:49.760 に答える