How to make composite component similar to <h:selectOneRadio />

对着背影说爱祢 提交于 2020-02-03 11:38:50

问题


I have been searching a lot for a way to make a composite component similar to: <h:selectOneRadio /> but I did not succeed.

I want something like:

<myowntags:selectOneRadio>
  <f:selectItem itemValue="value0" itemLabel="This is the value 0" />
  <f:selectItem itemValue="value1" itemLabel="This is the value 1" />
  <f:selectItem itemValue="value2" itemLabel="This is the value 2" />
</myowntags:selectOneRadio>

and:

<myowntags:selectOneRadio>
  <f:selectItems  value="#{controller.items}"  />
</myowntags:selectOneRadio>

As you can see, I want this composite component to have a child: <f:selectItem /> and render it the way I want.

Thanks in advance.


回答1:


You could check and iterate over them by #{cc.children}. The #{cc} refers to the current composite UIComponent instance which in turn has a getChildren() method. You could do kind of an instanceof check by checking the child's FQN (or simple name if that's sufficient) in the <cc:implementation>:

<c:forEach items="#{cc.children}" var="child">
    <c:set var="type" value="#{child['class'].simpleName}" />
    <c:if test="#{type == 'UISelectItem'}">
        <input type="radio" value="#{child.itemValue}" />#{child.itemLabel}<br/>
    </c:if>
    <c:if test="#{type == 'UISelectItems'}">
        <c:forEach items="#{child.value}" var="item">
            <input type="radio" value="#{item.value}" />#{item.label}<br/>
        </c:forEach>
    </c:if>
</c:forEach>

Your next problem is however collecting the submitted values. For that you'd need to implement the decode() method in the backing UIComponent which you reference by <cc:interface componentType>. Or, better, create a custom UIComponent with a Renderer instead. Taking over the Renderer's job in the view is clumsy.



来源:https://stackoverflow.com/questions/12509310/how-to-make-composite-component-similar-to-hselectoneradio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!