我怎么知道JSF组件的id,所以我可以在Javascript中使用

ftr*_*ers 43 javascript jsf

问题:有时你会想要从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>
Run Code Online (Sandbox Code Playgroud)

更新: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"/>
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,建议组件id上的属性inputText创建一个可以使用EL访问的对象#{myInptTxtId}.本文继续说明JSF 2.0将零参数getClientId()方法添加到UIComponent类中.从而允许#{myInptTxtId.clientId}上面提出的构造获得组件的实际生成的id.

虽然在我的测试中这不起作用.任何人都可以确认/否认.下面提出的答案具有上述技术没有的缺点.因此,了解上述技术是否真正有效会很好.

Bal*_*usC 56

您需要使用JSF在生成的HTML输出中分配的ID.右键单击Web浏览器中的页面,然后选择" 查看源".这正是JS看到的HTML代码(你知道,JS在webbrowser中运行并拦截HTML DOM树).

给出一个

<h:form>
    <h:inputText id="emailAddresses" ... />
Run Code Online (Sandbox Code Playgroud)

它看起来像这样:

<form id="j_id0">
    <input type="text" id="j_id0:emailAddress" ... />
Run Code Online (Sandbox Code Playgroud)

j_id0生成的HTML <form>元素的生成ID 在哪里.

您宁愿给所有JSF NamingContainer组件一个固定的,id以便JSF不会自动生成它们.这<h:form>是其中之一.

<h:form id="formId">
    <h:inputText id="emailAddresses" value="#{emailAddresses.emailAddressesStr}"/>
Run Code Online (Sandbox Code Playgroud)

这样,表单将不会获得自动生成的ID j_id0,输入字段将获得固定ID formId:emailAddress.然后你可以在JS中引用它.

var input = document.getElementById('formId:emailAddress');
Run Code Online (Sandbox Code Playgroud)

从那时起,您可以像往常一样继续使用JS代码.例如通过获得价值input.value.

也可以看看:


更新根据您的更新:你误解了这个博客的文章.特殊#{component}引用指的是评估EL表达式的当前组件,它仅适用于组件本身的任何属性.无论你想要什么,也可以实现如下:

var input = document.getElementById('#{emailAddress.clientId}');
Run Code Online (Sandbox Code Playgroud)

with(注意binding视图,你绝对不应该将它绑定到bean)

<h:inputText binding="#{emailAddress}" />
Run Code Online (Sandbox Code Playgroud)

但那很难看.更好地使用以下方法,其中将生成的HTML DOM元素作为JavaScript this引用传递给函数

<h:inputText onclick="show(this)" />
Run Code Online (Sandbox Code Playgroud)

function show(input) {
    alert(input.value);
}
Run Code Online (Sandbox Code Playgroud)

如果你正在使用jQuery,你甚至可以通过使用样式类作为标记接口来抽象它们

<h:inputText styleClass="someMarkerClass" />
Run Code Online (Sandbox Code Playgroud)

$(document).on("click", ".someMarkerClass", function() {
    var $input = $(this);
    alert($input.val());
});
Run Code Online (Sandbox Code Playgroud)

  • @maple:您只需要小心重复的ID.对于像这样的简单形式,你确实可以这样做.但对于视图中具有重复组件的复杂页面,您希望将其保留为默认值. (3认同)
  • 或者,您可以设置<h:form prependId ="false">,并且表单ID不会自己添加到DOM元素中. (2认同)

ftr*_*ers 6

答:所以这是我最开心的技巧.不需要做太多奇怪的事情来弄清楚组件的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"/>
Run Code Online (Sandbox Code Playgroud)

BackBean.java

UIInput emailAddyInputText;
Run Code Online (Sandbox Code Playgroud)

确保为此属性创建getter/setter.

  • 将组件绑定到bean是完全没必要的,只会增加bean的混乱.只需像我的答案更新的第一部分那样直接绑定到视图. (7认同)

Iva*_*hko 5

Id 是动态生成的,因此您应该为所有父元素定义名称,以避免类似 j_id123 的 id。

请注意,如果您使用 jQuery 来选择元素 - 则应在冒号前使用双斜杠:

    jQuery("my-form-id\\:my-text-input-block\\:my-input-id")
Run Code Online (Sandbox Code Playgroud)

代替:

    jQuery("my-form-id:my-text-input-block:my-input-id")
Run Code Online (Sandbox Code Playgroud)

如果是 Richfaces,您可以在 jsf 页面上使用 el 表达式:

    #{rich:element('native-jsf-input-id')} 
Run Code Online (Sandbox Code Playgroud)

选择 javascript 元素,例如:

    #{rich:element('native-jsf-input-id')}.value = "Enter something here";
Run Code Online (Sandbox Code Playgroud)