<h:selectOneRadio> 如何避免渲染表格元素?

23
有没有一种方法可以告诉JSF在使用时不要渲染元素呢? 我不使用表格,在这种情况下完全没有意义。 非常感谢您的任何帮助!
2个回答

27

JSF 2.3带有group属性

根据JSF规范问题329,我向<h:selectOneRadio>添加了一个新的group属性,这将使所有单选按钮组件都更加简单。在父级UIForm中具有相同group值的所有单选按钮组件将彼此分组。此外,除了单选按钮本身和(如果选择项目具有非空label)可选标签之外,它们不会呈现任何标记。如果有标签,则标签直接出现在单选按钮后面。

<!-- Just markup them the way you want! -->
<ul>
    <ui:repeat id="items" value="#{bean.items}" var="item">
        <li>
            <h:selectOneRadio group="foo" value="#{bean.selectedItem}">
                <f:selectItem itemValue="#{item}" />
            </h:selectOneRadio>
        </li>
    </ui:repeat>
</ul>

以下情况也是可能的。当存在多个具有相同“group”属性的组件时,并且缺少“value”属性和/或“UISelectItem”子元素,则它将引用该组的第一个组件的这些属性。
<h:selectOneRadio group="foo" value="#{bean.selectedItem}">
    <f:selectItems value="#{bean.availableItems}" />
</h:selectOneRadio>
<h:selectOneRadio group="foo" />
<h:selectOneRadio group="foo" />

<h:selectOneRadio group="foo" value="#{bean.selectedItem}">
    <f:selectItem itemValue="one" />
    <f:selectItem itemValue="two" />
    <f:selectItem itemValue="three" />
</h:selectOneRadio>
<h:selectOneRadio group="foo" />
<h:selectOneRadio group="foo" />

<h:selectOneRadio group="foo" value="#{bean.selectedItem}">
    <f:selectItem itemValue="one" />
</h:selectOneRadio>
<h:selectOneRadio group="foo">
    <f:selectItem itemValue="two" />
</h:selectOneRadio>
<h:selectOneRadio group="foo">
    <f:selectItem itemValue="three" />
</h:selectOneRadio>

<h:selectOneRadio group="foo" value="#{bean.selectedItem}">
    <f:selectItem itemValue="one" />
</h:selectOneRadio>
<h:selectOneRadio group="foo" value="#{otherBean.selectedItem}">
    <f:selectItem itemValue="two" />
</h:selectOneRadio>
<h:selectOneRadio group="foo" value="#{lastBean.selectedItem}">
    <f:selectItem itemValue="three" />
</h:selectOneRadio>

根据2.3.0-m07版本,它将在Mojarra中提供。

JSF 2.2使用透传元素

如果您已经使用JSF 2.2,请利用其新的透传元素/属性功能,通过明确设置name属性作为透传属性。为了在模型中设置提交的值,您只需要添加一个额外的<h:inputHidden>

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:jsf="http://xmlns.jcp.org/jsf"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:a="http://xmlns.jcp.org/jsf/passthrough">

...

<!-- Just markup them the way you want! -->
<ul>
    <ui:repeat id="items" value="#{bean.items}" var="item">
        <li>
            <input type="radio" jsf:id="item" a:name="#{hiddenItem.clientId}"
                value="#{item}" a:checked="#{item eq bean.selectedItem ? 'checked' : null}" />
            <h:outputLabel for="item" value="#{item}" />
        </li>
    </ui:repeat>
</ul>

<!-- This one won't display anything. -->
<h:inputHidden id="selectedItem" binding="#{hiddenItem}" value="#{bean.selectedItem}"
    rendered="#{facesContext.currentPhaseId.ordinal ne 6}" />

关于此问题的详细技术解释可以在这篇博客中找到:JSF 2.2中使用h:selectOneRadio自定义布局

PrimeFaces(JSF 2.x)

如果您正在使用PrimeFaces,则还可以使用<p:selectOneRadio layout="custom"><p:radioButton>

<html ... xmlns:p="http://primefaces.org/ui">

<!-- This one won't display anything. -->
<p:selectOneRadio id="foo" value="#{bean.selectedFoo}" layout="custom">
    <f:selectItems value="#{bean.availableFoos}" />
</p:selectOneRadio>

<!-- Just markup them the way you want! -->
<ul>
    <li><p:radioButton for="foo" itemIndex="0" /></li>
    <li><p:radioButton for="foo" itemIndex="1" /></li>
    <li><p:radioButton for="foo" itemIndex="2" /></li>
</ul>

你也可以循环遍历可用项,只需要在视图构建时间期间执行:

<ul>
    <c:forEach items="#{bean.availableFoos}" varStatus="loop">
        <li><p:radioButton for="foo" itemIndex="#{loop.index}" /></li>
    </c:forEach>
</ul>

Tomahawk(JSF 1.x或2.x)

如果您尚未使用JSF 2.2,或者您不喜欢PrimeFaces UI,则可使用Tomahawk的 <t:selectOneRadio>。它与<h:selectOneRadio>渲染相同的纯HTML输出,但支持layout="spread"属性,因此您可以通过<t:radio>按照自己的想法定位项目。

例如:

<html ... xmlns:t="http://myfaces.apache.org/tomahawk">

<!-- This one won't display anything. -->
<t:selectOneRadio id="foo" value="#{bean.selectedFoo}" layout="spread">
    <f:selectItems value="#{bean.availableFoos}" />
</t:selectOneRadio>

<!-- Just markup them the way you want! -->
<ul>
    <li><t:radio for="foo" index="0" /></li>
    <li><t:radio for="foo" index="1" /></li>
    <li><t:radio for="foo" index="2" /></li>
</ul>

自定义渲染器

提供一个自定义的Renderer。这只是一点点工作。从下面第一个"参见"链接开始:

参见:


在您的第二个PrimeFaces解决方案(使用forEach的那个),您如何为单选按钮添加标签?我似乎无法获取相应“input”元素的ID以在“h:outputLabel”元素中引用。 - jessepeng
@jessepeng:使用例如id="foo_#{loop.index}"。另请参见https://dev59.com/3nA75IYBdhLWcg3wW3kZ。 - BalusC
我下载了这个实现:https://mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.2.13,但是我找不到命名空间为passthrough的taglib.xml文件。这里只有compsoite、facelets、html_basic、jstl-core、jstl-fn、mojarra_ext和ui。passthrough应该在哪里? - Koray Tugay
@Koray:首先,该命名空间没有任何标签/函数。 - BalusC
@BausC 很有趣。Facelets处理器如何解析和处理这个命名空间? - Koray Tugay
显示剩余3条评论

2
我不确定这个方法是否对您足够合理,但是这是一个示例解决方案。
XHTML 代码:
<ui:repeat value="#{myBean.valueList}" var="radioValue">
    <input type="radio" name="radioSelection" value="#{radioValue}" checked="#{radioValue == myBean.selectedRadioValue ? 'checked' : ''}">#{radioValue}</input>
</ui:repeat>

后端Bean:

    private String selectedRadioValue;

    private List<Integer> valueList;

    public MyBean() {
        valueList = new ArrayList<Integer>();
        for (int i = 0; i < 15; i++) {
            valueList.add(i);
        }
    }

    public String getSelectedRadioValue() {
        return selectedRadioValue;
    }

    public List<Integer> getValueList() {
        return valueList;
    }

    public void actionMethod() {
        HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
        selectedRadioValue = request.getParameter("radioSelection");
    }

由于在XHTML中不能直接为单选按钮选择分配值,因此您需要从请求参数中获取它并在操作方法中手动分配它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接