自定义h:selectOneRadio与其他组件的布局和标签

时间:2015-02-17 18:55:56

标签: jsf layout jsf-2 customization selectoneradio

我想自定义<h:selectOneRadio>的默认布局。

在我的情况下,我需要在每个单选按钮后放一个<h:selectManyCheckbox>。这就是我到目前为止所做的:

<h:selectOneRadio value="#{user.Request}">
    <f:selectItem itemValue="Request1" itemLabel="Request1" />
    <f:selectItem itemValue="Request2" itemLabel="Request2" />
</h:selectOneRadio>

<h:selectManyCheckbox value="#{user.Request1}">
    <f:selectItem itemValue="Certificate1" itemLabel="Certificate1" />
    <f:selectItem itemValue="Certificate2" itemLabel="Certificate2" />
</h:selectManyCheckbox>

<h:selectManyCheckbox value="#{user.Request2}">
    <f:selectItem itemValue="Certificate3" itemLabel="Certificate3" />
    <f:selectItem itemValue="Certificate4" itemLabel="Certificate4" />
</h:selectManyCheckbox>

我试图在每个选择项目之后放置它们:

 <h:selectOneRadio value="#{user.Request}">
    <f:selectItem itemValue="Request1" itemLabel="Request1" />
    <h:selectManyCheckbox value="#{user.Request1}">
        <f:selectItem itemValue="Certificate1" itemLabel="Certificate1" />
        <f:selectItem itemValue="Certificate2" itemLabel="Certificate2" />
    </h:selectManyCheckbox>
    <f:selectItem itemValue="Request2" itemLabel="Request2" />
    <h:selectManyCheckbox value="#{user.Request2}">
        <f:selectItem itemValue="Certificate3" itemLabel="Certificate3" />
        <f:selectItem itemValue="Certificate4" itemLabel="Certificate4" />
    </h:selectManyCheckbox>
</h:selectOneRadio>

但它没有用。这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:4)

标准JSF <h:selectOneRadio>不支持此标记。

JSF组件库提供了更灵活的组件,例如Tomahawk<t:selectOneRadio layout="spread"><t:radio>

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

<!-- This one won't display anything. -->
<t:selectOneRadio id="request" value="#{user.request}" layout="spread">
    <f:selectItem itemValue="#{1}" itemLabel="Request 1" />
    <f:selectItem itemValue="#{2}" itemLabel="Request 2" />
    <f:ajax render="requests" />
</t:selectOneRadio>

<!-- Just markup them the way you want! -->
<h:panelGroup id="requests" layout="block">
    <ul>
        <li>
            <t:radio for="request" index="0" />
            <h:selectManyCheckbox value="#{user.request1}" disabled="#{user.request != 1}">
                ...
            </h:selectManyCheckbox>
        </li>
        <li>
            <t:radio for="request" index="1" />
            <h:selectManyCheckbox value="#{user.request2}" disabled="#{user.request != 2}">
                ...
            </h:selectManyCheckbox>
        </li>
    </ul>
</h:panelGroup>

PrimeFaces有一个类似的组件<p:selectOneRadio layout="custom"><p:radioButton>

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

<!-- This one won't display anything. -->
<p:selectOneRadio id="request" value="#{user.request}" layout="custom">
    <f:selectItem itemValue="#{1}" itemLabel="Request 1" />
    <f:selectItem itemValue="#{2}" itemLabel="Request 2" />
    <p:ajax update="requests" />
</p:selectOneRadio>

<!-- Just markup them the way you want! -->
<h:panelGroup id="requests" layout="block">
    <ul>
        <li>
            <p:radioButton for="request" itemIndex="0" />
            <h:selectManyCheckbox value="#{user.request1}" disabled="#{user.request != 1}">
                ...
            </h:selectManyCheckbox>
        </li>
        <li>
            <p:radioButton for="request" itemIndex="1" />
            <h:selectManyCheckbox value="#{user.request2}" disabled="#{user.request != 2}">
                ...
            </h:selectManyCheckbox>
        </li>
    </ul>
</h:panelGroup>

无论哪种方式,只需让复选框组的disabled属性检查当前选中的单选按钮值(我已将其明确更改为Long,但可能会enum更多自我记录),并使用通常的ajax魔法在更改事件期间部分更新视图。

如果由于某种原因不能重用现有JSF组件库中的增强组件,那么您需要自己编写所有内容。最简单的是覆盖标准<h:selectOneRadio>渲染器以识别新的layout属性,然后像上述组件一样生成所需的HTML输出。另见a.o. How to override h:selectOneRadio renderer? Where is the renderer class in jsf-impl?