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>

选择一个单选按钮会取消选择另一个单选按钮,并且该单选按钮将在回发时保持选中状态。(当渲染相同的视图时)

但是,当我们处理像 一样的迭代组件<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选择一个无线电按钮时,请删除其他广播按钮 -

            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

The root problem is, HTML radio buttons are grouped based on their nameattribute, so the webbrowser knows which others to unselect when one is selected. 但是 JSF 通过设计为每个项目生成一个不同的<h:dataTable>项目,其中行索引内联,因此它们不能被分组,因此是基于 JavaScript 的解决方法。

从 JSF 2.2 开始,通过新的传递元素和属性特性,可以将name属性强制为您选择的值并通过 helper 捕获所选项目<h:inputHidden>。这在我去年的另一篇博客文章中得到了充实:JSF 2.2 中使用 h:selectOneRadio 的自定义布局。本文以本文<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 回答