【问题标题】:How can I know the id of a JSF component so I can use in Javascript如何知道 JSF 组件的 id 以便在 Javascript 中使用
【发布时间】:2011-05-18 13:16:16
【问题描述】:

问题: 有时你会想从 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。

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

【问题讨论】:

    标签: javascript jsf


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您需要完全使用 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获取价值。

      另见:


      更新根据您的更新:您误解了博客文章。特殊的#{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
      【解决方案3】:

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

      【讨论】:

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

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

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

      在你的 JavaScript 中:

      jQuery('.emailAddressesForSelector');
      

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

      【讨论】:

      【解决方案5】:
      <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
      

      【讨论】:

        【解决方案6】:

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

        【讨论】:

        • id是自动生成的。
        猜你喜欢
        • 2015-06-02
        • 2018-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多