在JavaScript中访问JSF嵌套复合组件元素
我正在尝试使用复合组件来关闭JSF2项目中的弹出窗口 此代码库使用Icefaces 3.3.0(出于历史原因,其1.8.2兼容层)、Mojarra 2.2.7和Glassfish 4.1 我有一个input.xhtml,它提供了文本输入,并使用了一个2按钮弹出窗口(ok/cancel),这反过来又建立在基本弹出窗口的基础上 input.xhtml:在JavaScript中访问JSF嵌套复合组件元素,jsf,jsf-2,icefaces,composite-component,Jsf,Jsf 2,Icefaces,Composite Component,我正在尝试使用复合组件来关闭JSF2项目中的弹出窗口 此代码库使用Icefaces 3.3.0(出于历史原因,其1.8.2兼容层)、Mojarra 2.2.7和Glassfish 4.1 我有一个input.xhtml,它提供了文本输入,并使用了一个2按钮弹出窗口(ok/cancel),这反过来又建立在基本弹出窗口的基础上 input.xhtml: <composite:interface> <!-- ... --> <composite:edita
<composite:interface>
<!-- ... -->
<composite:editableValueHolder name="forInput" targets="theInput"/>
</composite:interface>
<composite:implementation>
<my:popup2Buttons>
<ice:inputText id="theInput" value="..."/>
<script>setInputFocus("#{cc.clientId}:theInput");</script>
</my:popup2Buttons>
</composite:implementation>
setInputFocus(“#{cc.clientId}:输入”);
popup2buttons.xhtml:
<composite:interface>
<!-- ... -->
</composite:interface>
<composite:implementation>
<my:popup>
<composite:insertChildren/>
<ice:commandButton id="OkButton"
value="Ok"
actionListener="..."/>
<ice:commandButton id="CancelButton"
value="Cancel"
actionListener="..."/>
</my:popup>
</composite:implementation>
popup.xhtml:
<composite:interface>
<!-- ... -->
</composite:interface>
<composite:implementation>
<script>
function setInputFocus(id) {
document.getElementById(id).focus();
}
</script>
<ice:panelPopup>
<f:facet name="body">
<h:panelGroup>
<composite:insertChildren/>
</h:panelGroup>
</f:facet>
</ice:panelPopup>
</composite:implementation>
函数setInputFocus(id){
document.getElementById(id.focus();
}
弹出窗口的工作原理与预期基本相同,即我可以输入一些内容,ok和cancel按钮可以工作,验证也可以工作
不起作用的是我的JavaScript代码,它试图在弹出窗口打开时集中输入
当我在Firebug中查看页面时,我看到输入的ID是MyForm:j_idt63:j_idt64:j_idt67:theInput
,但是JavaScript代码试图将ID为MyForm:j_idt63:theInput
的元素作为焦点
为什么input.xhtml
中的#{cc.clientId}
不是输入后来得到的正确ID?我需要做些什么才能让它工作
我已经看到了,但我不想要绑定,这样复合组件就可以独立于任何支持bean
这里还有什么我遗漏的吗?复合组件是隐式的。即,他们在孩子的客户ID前加上自己的ID。这使得在同一视图中使用多个它们成为可能,而它们的子对象不会在生成的HTML输出中导致重复ID 在您的特定情况下,您将输入字段包装在另一个组合中,而该组合又包装在另一个组合中。如果您完全肯定在这个特定的组合中不需要多个命名容器相互包装,那么这些(
popup2buttons.xhtml
和popup.xhtml
)可能不应该是复合的,而应该是
模板或
标记文件。另见
回到技术问题上来,这是因为{cc.clientId}
没有引用嵌套复合组件的ID,而是引用当前复合组件的ID。因此,这将是关闭的。至于使用绑定的潜在解决方案
,您找到的答案没有告诉您应该为此使用支持bean。答案中的binding=“#{foo}”
代码保持原样。它确实是这样工作的,没有bean属性,请参见。但是,当您在同一视图中多次包含同一个组合,因此多个组件共享相同的binding=“#{foo}”
时,此构造确实会失败。它确实不应该由多个组件共享,另请参见
要在没有支持bean的情况下解决这个问题,可以使用所谓的支持组件
com.example.InputComposite
@FacesComponent("inputComposite")
public class InputComposite extends UINamingContainer {
private UIInput input;
// +getter+setter.
}
input.xhtml
<cc:interface componentType="inputComposite">
...
</cc:interface>
<cc:implementation>
...
<h:inputText binding="#{cc.input}" ... />
<script>setInputFocus("#{cc.input.clientId}");</script>
...
</cc:implementation>
...
...
setInputFocus(“#{cc.input.clientId}”);
...
另一种方法是将它们重新加工成模板或标记文件。注意不要过度评价/过度使用复合材料。绑定方法似乎只适用于输入,而不适用于
命令按钮等。这是正确的还是我遗漏了什么?当我向按钮添加binding=“#{okButton}”
属性时,它不会被渲染。这不是原始问题的一部分;我尝试在输入上设置onKeyPress事件处理程序,并在用户按enter键时单击ok按钮,在用户按esc键时单击cancel按钮。如果多个按钮组件共享相同的绑定
,则可能会发生这种情况。您应该使用binding=“#{cc.okButton}”
,如答案中所述。