我怎样才能知道一个JSF组件的ID,所以我可以在Javascript中使用
问题:有时候你想用getElementById
从javascript访问一个组件,但是id是在JSF中动态生成的,所以你需要一个获取对象id的方法。 我在下面回答你如何做到这一点。
原问题:我想用下面的代码。 我如何在Javascript中引用inputText JSF组件?
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <head> <title>Input Name Page</title> <script type="javascript" > function myFunc() { // how can I get the contents of the inputText component below alert("Your email address is: " + document.getElementById("emailAddress").value); } </script> </head> <h:body> <f:view> <h:form> Please enter your email address:<br/> <h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/> <h:commandButton onclick="myFunc()" action="results" value="Next"/> </h:form> </f:view> </h:body> </html>
更新 :这篇文章JSF2.0中的客户端标识符讨论了使用如下技术:
<script type="javascript" > function myFunc() { alert("Your email address is: " + document.getElementById("#{myInptTxtId.clientId}").value); } </script> <h:inputText id="myInptTxtId" value="backingBean.emailAddress"/> <h:commandButton onclick="myFunc()" action="results" value="Next"/>
在上面的例子中,建议inputText
组件的属性id
创建一个对象,可以使用#{myInptTxtId}
在EL中访问该对象。 本文继续指出,JSF 2.0为UIComponent
类添加了零参数getClientId()
方法。 从而允许上面建议的#{myInptTxtId.clientId}
结构获取组件的实际生成的ID。
虽然在我的测试中这不起作用。 任何人都可以确认/否认。 下面建议的答案有缺点,上述技术没有。 因此,知道上述技术是否真正起作用是很好的。
您需要使用JSF在生成的HTML输出中分配的ID。 右键单击Web浏览器中的页面,然后选择查看源代码 。 这正是JS看到的HTML代码(你知道,JS在web浏览器中运行并在HTML DOM树上拦截)。
鉴于一个
<h:form> <h:inputText id="emailAddresses" ... />
它看起来像这样:
<form id="j_id0"> <input type="text" id="j_id0:emailAddress" ... />
其中j_id0
是生成的HTML <form>
元素的生成ID。
您宁愿给所有的JSF NamingContainer
组件一个固定的id
这样JSF就不会自动生成它们。 <h:form>
就是其中之一。
<h:form id="formId"> <h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
这样,表单将不会得到像j_id0
这样的自动生成的ID,并且输入字段将获得formId:emailAddress
的固定ID。 那么你可以在JS中引用它。
var input = document.getElementById('formId:emailAddress');
从这一点上,你可以照常继续使用JS代码。 例如通过input.value
获取价值。
也可以看看:
- 如何使用jQuery选择JSF组件?
根据您的更新更新:您误解了博客文章。 特殊的#{component}
引用引用EL表达式被评估的当前组件,这只能在组件本身的任何属性中使用。 无论你想要什么,也可以实现如下:
var input = document.getElementById('#{emailAddress.clientId}');
(注意binding
到视图,你绝对不应该绑定到一个bean)
<h:inputText binding="#{emailAddress}" />
但这很丑陋。 更好地使用以下方法,其中将生成的HTML DOM元素作为JavaScript的参考传递给该函数
<h:inputText onclick="show(this)" />
同
function show(input) { alert(input.value); }
如果你使用jQuery,甚至可以通过使用风格类作为标记接口对它们进行抽象,从而更进一步
<h:inputText styleClass="someMarkerClass" />
同
$(document).on("click", ".someMarkerClass", function() { var $input = $(this); alert($input.val()); });
答:所以这是我最喜欢的技术。 不需要做太多奇怪的事情来找出一个组件的ID。 记住这一点,所以你可以从页面的任何地方知道组件的id
,而不仅仅是从实际的组件本身。 这是关键。 我按下按钮,启动JavaScript函数,它应该能够访问任何其他组件,而不仅仅是启动它的一个组件。
这个解决方案不需要任何“右键单击”,看看这个ID是什么。 这种类型的解决方案是脆弱的,因为id是动态生成的,如果我改变页面,我将不得不每次都经历那些无稽之谈。
-
将组件绑定到后台bean。
-
在任何你想要的地方引用绑定的组件。
所以这里是一个如何做的样本。
假设:我有一个* .xhtml页面(可能是* .jsp),我已经定义了一个支持bean。 我也使用JSF 2.0。
* .xhtml页面
<script> function myFunc() { var inputText = document.getElementById("#{backBean.emailAddyInputText.clientId}") alert("The email address is: " + inputText.value ); } </script> <h:inputText binding="#{backBean.emailAddyInputText}"/> <h:commandButton onclick="myFunc()" action="results" value="Next"/>
BackBean.java
UIInput emailAddyInputText;
一定要为这个属性创建你的getter / setter。
Id是动态生成的,因此您应该为所有父元素定义名称,以避免类似j_id123的id。
请注意,如果你使用jQuery来选择元素 – 比你应该在冒号前使用双斜杠:
jQuery("my-form-id\\:my-text-input-block\\:my-input-id")
代替:
jQuery("my-form-id:my-text-input-block:my-input-id")
在Richfaces的情况下,您可以在jsf页面上使用el表达式:
#{rich:element('native-jsf-input-id')}
选择javascript元素,例如:
#{rich:element('native-jsf-input-id')}.value = "Enter something here";
您可以在生成HTML源代码时查看HTML源代码,并查看设置的ID,以便在JavaScript中使用它。 因为它在一个表单中,所以可能会在表单标识前加上。
我知道这不是JSF的方式,但如果你想避免身份痛苦,你可以为选择器设置一个特殊的CSS类。 只要确保使用一个好名字,以便当有人读取类名时,很明显,它是用于此目的。
<h:inputText id="emailAddresses" class="emailAddressesForSelector"...
在你的JavaScript中:
jQuery('.emailAddressesForSelector');
当然,你仍然需要手动管理类名的唯一性。 我认为这是可维护的,只要你不使用可重用的组件。 在这种情况下,您可以使用约定生成类名称。