1

このような通常の状況では:

  <h:form>           
    <h:selectOneRadio value="#{bean.gender}">
        <f:selectItem itemValue="Male" itemLabel="Male" />
        <f:selectItem itemValue="Female" itemLabel="Female" />
        <f:selectItem itemValue="Other" itemLabel="Other" />
    </h:selectOneRadio>
    <h:commandButton value="Submit" action="#{bean.action}" />
  </h:form>

1 つのラジオ ボタンを選択すると、もう 1 つのラジオ ボタンが選択解除され、ラジオ ボタンはポストバックで選択されたままになります。(同じビューがレンダリングされる場合)

ただし、 のような反復コンポーネントを扱っている場合<h:dataTable>、選択は失われます。

スニペットを検討してください:

        <h:form id="hashMapFormId">           
            <b>HASH MAP:</b>
            <h:dataTable value="#{playersBean.dataHashMap.entrySet()}" var="t" border="1">
                <h:column>
                    <f:facet name="header">Select</f:facet>
                    <h:selectOneRadio id="radiosId" onclick="deselectRadios(this.id);" 
                                        value="#{playersBean.select}">
                        <f:selectItem itemValue="null"/>
                    </h:selectOneRadio>
                </h:column> 
            </h:dataTable>
            <h:commandButton value="Show Hash Map Selection" 
                             action="#{playersBean.showSelectedPlayer()}" />
        </h:form>

シンプルな JavaScript で実装されている 1 つのラジオ ボタンが選択されているときに、他のラジオ ボタンの選択を解除すると、

            function deselectRadios(id) {

                var f = document.getElementById("hashMapFormId");
                for (var i = 0; i < f.length; i++)
                {
                    var e = f.elements[i];
                    var eid = e.id;
                    if (eid.indexOf("radiosId") !== -1) {
                        if (eid.indexOf(id) === -1) {
                            e.checked = false;
                        } else {
                            e.checked = true;
                        }
                    }
                }
            }

GET リクエストを発行します。
ここに画像の説明を入力

ラジオ ボタンを選択します。
ここに画像の説明を入力

次に、送信ボタンを押します。応答:
ここに画像の説明を入力

ポストバック時にラジオ ボタンが選択されていないことがわかります。この欠点を解決する方法は?

これは、このコンポーネント属性itemValuenull次のとおりであるためであることをよく知っています。

<f:selectItem itemValue="null"/>
4

1 に答える 1

2

このトリックは、JSF 1.x / 2.0/2.1<h:selectOneRadio><h:dataTable>. このトリックは、私の 10 年前のブログ記事Using Datatables - Select row by radio buttonに端を発しています。

根本的な問題は、HTML ラジオ ボタンがその属性に基づいてグループ化されてnameいるため、Web ブラウザは、選択されている他のボタンを選択解除する必要があることを認識していることです。しかし、JSF は設計上、行インデックスがインライン化されたアイテムごとに異なるものを生成する<h:dataTable>ため、グループ化できないため、JavaScript ベースの回避策が必要です。

ただし、JSF 2.2 以降、新しいpassthrough 要素と属性機能により、属性を選択した値に強制しname、ヘルパーを介して選択したアイテムをキャプチャすることができます<h:inputHidden>。これは、昨年の私の別のブログ記事で具体化されています: Custom layout with h:selectOneRadio in JSF 2.2。この記事では<ui:repeat>例として使用していますが、これは次のように書き換えることができ<h:dataTable>ます。

<h:form>
    <h:dataTable value="#{bean.items}" var="item">
        <h:column>
            <input type="radio" jsf:id="item" a:name="#{hiddenItem.clientId}"
                value="#{item.id}" a:checked="#{item.id eq bean.selectedItemId ? 'checked' : null}" />
        </h:column>
        <h:column>#{item.id}</h:column>
        <h:column>#{item.name}</h:column>
    </h:dataTable>
    <h:inputHidden id="selectedItem" binding="#{hiddenItem}" value="#{bean.selectedItemId}"
        rendered="#{facesContext.currentPhaseId.ordinal ne 6}" />
    <h:commandButton id="submit" value="Submit" action="#{bean.submit}" />
</h:form>

@Named
@ViewScoped
public class Bean implements Serializable {

    private List<Item> items;
    private Long selectedItemId;

    // ...

    public void submit() {
        System.out.println("Selected item ID: " + selectedItemId);
    }

    // ...
}

はい、選択したラジオボタンは、この方法でポストバック時に選択されたままになります。エンティティ全体を渡すこともできます。これには、 のコンバーターのみが必要<h:inputHidden>です。

于 2016-06-26T14:07:39.780 に答える