我如何知道 JSF 组件的 id 以便可以在 Javascript 中使用

Posted

技术标签:

【中文标题】我如何知道 JSF 组件的 id 以便可以在 Javascript 中使用【英文标题】:How can I know the id of a JSF component so I can use in Javascript 【发布时间】:2011-08-28 01:37:54 【问题描述】:

问题: 有时你会想从 javascript 访问一个组件 getElementById,但是 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>

更新:这篇帖子Client Identifiers in 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 创建一个可以通过 EL 使用#myInptTxtId 访问的对象, 在上面的例子中。文章继续指出 JSF 2.0 添加了 UIComponent 类的零参数 getClientId() 方法。 从而允许建议 #myInptTxtId.clientId 构造 以上获取组件实际生成的id。

虽然在我的测试中这不起作用。其他人可以确认/否认。 下面建议的答案存在上述问题的缺点 技术不行。所以很高兴知道上述技术是否 确实有效。

【问题讨论】:

【参考方案1】:

您需要完全使用 JSF 在生成的 HTML 输出中指定的 ID。在您的网络浏览器中右键单击该页面并选择查看源代码。这正是 JS 看到的 HTML 代码(你知道,JS 在 webbrowser 中运行并在 HTML DOM 树上拦截)。

给定一个

<h:form>
    <h:inputText id="emailAddresses" ... />

它看起来像这样:

<form id="j_id0">
    <input type="text" id="j_id0:emailAddress" ... />

其中j_id0 是生成的HTML &lt;form&gt; 元素的生成ID。

您宁愿为所有 JSF NamingContainer 组件提供一个固定的 id,以便 JSF 不会自动生成它们。 &lt;h:form&gt; 就是其中之一。

<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获取价值。

另见:

How to select JSF components using jQuery?

更新根据您的更新:您误解了博客文章。特殊的#component 引用指的是评估 EL 表达式的 current 组件,这仅适用于组件本身的任何属性。你想要的也可以如下实现:

var input = document.getElementById('#emailAddress.clientId');

with(注意视图的binding,你应该将absolutely not绑定到一个bean)

<h:inputText binding="#emailAddress" />

但这太丑了。最好使用以下方法,将生成的 HTML DOM 元素作为 JavaScript this 引用传递给函数

<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 不会将自身添加到您的 DOM 元素中。
@maple:你只需要小心重复的 id。对于像这样的简单形式,您确实可以这样做。但是对于在视图中具有重复组件的复杂页面,您希望将其保留为默认值。 我的主要目标是内部组件通信可以这么说。您的解决方案不允许单击按钮并触发访问页面中任何其他组件的 javascript。请参阅下面的答案以获得更好的解决方案。 你为什么要把它绑定到backing bean?那只是混乱。就像我的答案更新的第一部分一样,立即绑定到视图。 @BalusC 虽然我给我的 p:commandButton 提供了一个名为 speak out 的固定 ID,但它仍然会自动生成一个名为 id="j_idt39:speakout" 的 ID【参考方案2】:

答案:所以这是我最满意的技术。不需要做 太多奇怪的事情来找出组件的 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。

【讨论】:

将组件绑定到 bean 是完全没有必要的,只会给 bean 添加混乱。就像我的答案更新的第一部分一样直接绑定到视图。【参考方案3】:

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";

【讨论】:

【参考方案4】:

您可以在生成它时查看 HTML 源代码并查看 id 设置为什么,以便您可以在 JavaScript 中使用它。因为它是在一个表单中,所以它可能会在它前面加上表单 ID。

【讨论】:

id是自动生成的。【参考方案5】:

我知道这不是 JSF 方式,但如果你想避免 ID 的痛苦,你可以为选择器设置一个特殊的 CSS 类。只要确保使用一个好的名称,这样当有人阅读类名时,就可以清楚地知道它是用于此目的的。

<h:inputText id="emailAddresses" class="emailAddressesForSelector"...

在你的 JavaScript 中:

jQuery('.emailAddressesForSelector');

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

【讨论】:

使用 jQuery 选择器应该很容易找到元素。但对我来说,ID 中的冒号(我认为这是不允许的)看起来像是把它弄乱了,导致选择器不起作用:***.com/questions/609382/jquery-selector-id-ends-with @PanuHaaramo 你可以转义特殊字符【参考方案6】:
<h:form  id="myform">
 <h:inputText  id="name" value="#beanClass.name" 
                a:placeholder="Enter Client Title"> </h:inputText>
</h:form>

这是一个jsf的小例子。现在我将编写javascript代码来获取上述jsf组件的值:

    var x = document.getElementById('myform:name').value; //here x will be of string type

   var y= parseInt(x,10); //here we converted x into Integer type and can do the 
                           //arithmetic operations as well

【讨论】:

以上是关于我如何知道 JSF 组件的 id 以便可以在 Javascript 中使用的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JSF 复合组件使页面上的 id 唯一?

如何在 JSF 中创建现有组件的组合?

根据用户角色渲染 JSF 组件

如何使用 jQuery 选择 JSF 组件?

如何使用 jQuery 选择 JSF 组件?

在 JSF 中按 ID 查找组件