【问题标题】:<h:selectOneRadio> renders table element, how to avoid this?<h:selectOneRadio> 渲染表格元素,如何避免这种情况?
【发布时间】:2011-11-18 02:25:07
【问题描述】:

有没有办法告诉 JSF 在使用 &lt;h:selectOneRadio&gt; 时它不应该呈现 &lt;table&gt; 元素? 我不使用表格,在这种情况下绝对没有意义。

感谢任何帮助!

【问题讨论】:

    标签: jsf html-table selectoneradio


    【解决方案1】:

    带有group 属性的JSF 2.3

    根据JSF spec issue 329,我向&lt;h:selectOneRadio&gt; 添加了一个新的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,请利用其新的 passthrough elements/attribtues 功能,从而将 name 属性显式设置为传递属性。为了在模型中设置提交的值,你只需要一个额外的&lt;h:inputHidden&gt;

    <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}" />
    

    深入的技术解释可以在这个博客中找到:Custom layout with h:selectOneRadio in JSF 2.2

    PrimeFaces (JSF 2.x)

    如果你碰巧使用PrimeFaces,那么你也可以使用&lt;p:selectOneRadio layout="custom"&gt;&lt;p:radioButton&gt;

    <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>
    

    你也可以循环遍历可用的项目,你只需要在view build time期间进行:

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

    战斧(JSF 1.x 或 2.x)

    如果您还没有使用 JSF 2.2 或者您不喜欢 PrimeFaces UI,请使用 Tomahawk's &lt;t:selectOneRadio&gt;,它呈现与 &lt;h:selectOneRadio&gt; 相同的纯 HTML 输出,但支持 layout="spread" 属性,以便您可以按您想要的方式通过&lt;t:radio&gt; 定位项目。

    例如

    <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 的解决方案)中,您将如何向单选按钮添加标签?我似乎无法获得要在 h:outputLabel 元素中引用的各个 input 元素的 ID。
    • @jessepeng:使用例如id="foo_#{loop.index}"。另见 a.o. stackoverflow.com/q/3342984
    • 使用该方法,仅引用单选按钮的封闭 div,如下所示:&lt;div id="cQueryEditor:opt_2" class="ui-radiobutton ui-radiobutton-native ui-widget"&gt;...&lt;/div&gt; &lt;label for="cQueryEditor:opt_2"&gt;...&lt;/label&gt;。顺便说一句,我使用的是 PrimeFaces 的朴素风格。
    • 我下载了这个实现:mvnrepository.com/artifact/com.sun.faces/jsf-impl/2.2.13,但我找不到命名空间的 taglib.xml 文件:直通。这里只有 compsoite、facelets、html_basic、jstl-core jstl-fn、mojarra_ext 和 ui。通道应该在哪里?
    • @Koray:该命名空间首先没有任何标签/功能。
    【解决方案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 上为单选选择分配值,因此您需要从请求参数中获取它并在您的操作方法中手动分配它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 2020-07-21
      相关资源
      最近更新 更多