我怎样才能知道一个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是动态生成的,如果我改变页面,我将不得不每次都经历那些无稽之谈。

  1. 将组件绑定到后台bean。

  2. 在任何你想要的地方引用绑定的组件。

所以这里是一个如何做的样本。

假设:我有一个* .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'); 

当然,你仍然需要手动管理类名的唯一性。 我认为这是可维护的,只要你不使用可重用的组件。 在这种情况下,您可以使用约定生成类名称。