1

こんにちは、JSF達人です。

カスタム レンダラーと ajax ハンドラーに関するヘルプを探しています。私たちのプロジェクトでは、通常のラジオ ボタンとチェック ボックスのレンダラーをテーブルでレンダリングするため使用できません。これは会社の基準に反しています。サードパーティのコンポーネント ライブラリも使用できません。

いくつかのプロジェクトで使用したカスタム レンダラーが正常に動作するようになりました。ただし、この特定のプロジェクトでは、いくつかのラジオ ボタンの ajax クリック ハンドラーをレンダリングする必要があります。この質問への回答のアドバイスに従って、呼び出しを追加しRenderKitUtils.renderSelectOnclick();、標準レンダラーと同じ JavaScript をレンダリングするように見えますが、実際には、firebug ネットワーク パネルに送信要求が表示されますが、値変更リスナーが起動されず、私は理由についてのヘルプを探しています (標準のレンダラーで問題なく動作します)

いくつかのコード: まず、ajax ハンドラーの作成 (ラジオ ボタンはプログラムで作成されます)

          AjaxBehavior valueChangeAction = (AjaxBehavior) FacesUtils.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);

        valueChangeAction.addAjaxBehaviorListener(new ProbeQuestionListener(currentQuestion, "probeDiv" + questionNumber,
            probeDiv));

        selectUI.addClientBehavior("valueChange", valueChangeAction);
        valueChangeAction.setRender(Collections.singletonList("probeDiv" + questionNumber));

標準のレンダラーでは、次のものが生成されます。

<table id="answer_1" class="marginLeft1a">
  <tbody>
    <tr>
      <td>
        <input id="answer_1:0" type="radio" onclick="mojarra.ab(this,event,'valueChange',0,'probeDiv2')" value="0" name="answer_1">
        <label for="answer_1:0"> Yes</label>
      </td><td>
         <input id="answer_1:1" type="radio" onclick="mojarra.ab(this,event,'valueChange',0,'probeDiv2')" value="1" name="answer_1">
         <label for="answer_1:1"> No</label>
     </td>
  </tr>

そしてすべてが順調です。ajax リクエストが送信され、サーバー側のリスナーが起動します。

カスタム レンダラーの関連部分:

 public void encodeEnd(final FacesContext p_context, final UIComponent p_component) throws IOException {

    /* set up convenience fields */
    context = p_context;
    component = p_component;
    componentId = component.getClientId(context);

    // rendering divs etc omitted.

    while (iterator.hasNext()) {
        final UIComponent childComponent = iterator.next();
        // irrelevant code omited
        if ("javax.faces.SelectItem".equals(childComponent.getFamily())) {
            renderSelectItem(idIndex, childComponent);
            idIndex++;
        }
     }
 }

private void renderSelectItem(final int p_idIndex, final UIComponent p_childComponent) throws IOException {
        // unrelated code omitted
        writer.startElement("input", component);
        writer.writeAttribute("type", getInputType(), null);
        writer.writeAttribute("id", p_childComponentId, "id");
        writer.writeAttribute("name", componentId, "clientId");
        RenderKitUtils.renderSelectOnclick(context, component, false);
        writer.endElement("input");
        // unrelated code omitted
}

更新:私のレンダラーの基本クラスのデコード メソッドは次のとおりです。

    @Override
public void decode(final FacesContext p_context, final UIComponent p_component) {

    final Map<String, String> valuesMap = p_context.getExternalContext().getRequestParameterMap();

    final UIInput input = (UIInput) p_component; // NOSONAR

    final Object value = valuesMap.get(input.getClientId(p_context));
    // System.out.println("radio button decode: found " + value);
    input.setSubmittedValue(value);
}

これは次のようにレンダリングされます。

<span class="marginLeft1a" id="answer_1">
    <label for="answer_1:0">
    <input type="radio" value="0" onclick="mojarra.ab(this,event,'valueChange',0,'probeDiv2')" name="answer_1" id="answer_1:0"> 
     Yes
     </label>
     <label for="answer_1:1">
       <input type="radio" value="1" onclick="mojarra.ab(this,event,'valueChange',0,'probeDiv2')" name="answer_1" id="answer_1:1"> 
       No
     </label>
</span>

ご覧のとおり、input タグの name および id 属性値と同様に、javaScript クリック ハンドラーは同一です。これにより Ajax リクエストがトリガーされますが、リスナーは最初のバージョンのようにサーバー側で起動されません。

何か案は ?

4

1 に答える 1