我必须将三态复选框实现为具有ajax功能的复合组件。 这就是我到目前为止所做的:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<cc:interface>
<cc:attribute name="id" /><!-- necessary? -->
<cc:attribute name="value" required="false" />
<cc:clientBehavior name="change" event="change" targets="value" />
</cc:interface>
<cc:implementation>
<div style="float: left;">
<h:outputStylesheet library="default" name="css/checkbox.css" target="head" />
<h:outputScript library="default" name="js/checkbox.js" target="head" />
<div id="#{cc.clientId}" class="cc-checkbox cc-checkbox-value#{cc.attrs.value}"
style="width: 14px; height: 14px;" onclick="checkboxToggleControl('#{cc.clientId}')"></div>
<h:inputHidden id="value" value="#{cc.attrs.value}" />
</div>
</cc:implementation>
</ui:composition>
如您所见(或不是,因为我没有包含JS,因为它不是问题),一个小型JavaScript将用户看到的类替换为三态复选框(null
,{{1 },true
)。当前值由JavaScript存储在false
中。
我希望能够在使用控件时注册ajax事件,以便能够将值存储在服务器上。该组件位于<h:inputHidden>
内。每次用户点击它时,该值应“立即”存储在数据库中。将<rich:extendedDataTable>
与clientBehaviour
一起使用不起作用,因为它不支持ajax。
是否可以使用inputHidden
来解析<h:inputHidden>
?有什么缺点? (我不得不处理验证,不是吗?)
有没有其他方法可以将其作为复合组件实现?
或者,编写“真实”组件会“更容易”吗?
我没有使用<h:inputText>
,因为CSS无法以所需方式设置样式,也因为它不支持三态。
答案 0 :(得分:4)
确实,<f:ajax change>
不支持<h:inputHidden>
。您只会得到以下异常,因为组件后面的HtmlInputHidden
class未实现ClientBehaviorHolder
interface:
javax.faces.view.facelets.TagException: /test.xhtml @23,52 <f:ajax> Unable to attach <f:ajax> to non-ClientBehaviorHolder parent
您确实需要用<h:inputText>
替换它。您可以使用CSS display:none;
隐藏它。您只需要意识到通过JavaScript操纵其值不会自动触发任何HTML DOM事件。您需要通过在HTML DOM元素上显式调用change
来手动触发onchange()
事件:
var input = document.getElementById(...);
input.value = newValue;
input.onchange();
或者,如果你碰巧总体上使用jQuery,
var $input = $("#...");
$input.val(newValue);
$input.change(); // Or $input.trigger("change");
无关具体问题,关于此处评论中的问题:
<cc:attribute name="id" /><!-- necessary? -->
仅用于纪录片目的。即当你真正使用shortDescription
时。
<cc:attribute name="id" shortDescription="The ID of the composite." />
但是否则它已经从UIComponent
基类继承(如binding
和rendered
)。