动态Id';JSF/Seam中的s

动态Id';JSF/Seam中的s,jsf,seam,Jsf,Seam,我正在开发的Seam应用程序出现了一个小问题,我想知道是否有人知道解决这个问题的方法。我的应用程序中有一个表单,它使用AJAX根据下拉框中的项目显示特定的输入框。除了在我的输入框中设置ID之外,代码工作正常。看起来JSF不允许我通过变量设置ID。标签中的其他属性(如“for”)也可以。下面是一些代码来解释我的意思: <ui:repeat value="#{serviceHome.instance.serviceSettings}" var="currSetting" > <

我正在开发的Seam应用程序出现了一个小问题,我想知道是否有人知道解决这个问题的方法。我的应用程序中有一个表单,它使用AJAX根据下拉框中的项目显示特定的输入框。除了在我的输入框中设置ID之外,代码工作正常。看起来JSF不允许我通过变量设置ID。标签中的其他属性(如“for”)也可以。下面是一些代码来解释我的意思:

<ui:repeat value="#{serviceHome.instance.serviceSettings}" var="currSetting" >
  <li>
    <!-- Imagine the below works out as "settingABC" -->
    <c:set var="labelKey" value="setting#{jsfUtils.removeWhitespace(currSetting.key.name)}" />

    <!-- Labelkey is correctly added into this input so for = "settingABC" -->
    <h:outputLabel for="#{labelKey}" styleClass="required generated" value="#{currSetting.key.name}:"/>

    <s:decorate styleClass="errorwrapper">

      <!-- Labelkey ISN'T correctly added into this input. Instead we just get "setting" -->
      <h:inputText id="#{labelKey}" value="#{currSetting.value}"/>

      <a4j:outputPanel ajaxRendered="true">
        <h:message for="#{labelKey}" styleClass="errormessage" />
      </a4j:outputPanel>
    </s:decorate>
  </li>
</ui:repeat>


  • 有人知道我如何克服这个问题吗?

    我假设您希望控制输入组件的ID,以便稍后在Javascript中引用它

    由于无法通过表达式设置ID,因此我执行以下操作:

    <h:inputText id="whatever" value="..." />
    

    希望能有帮助。

    你明白为什么他们不让你设置ID了吧?JSF接管了id的创建,因为您处于一个重复的组件循环中,如果组件允许您只设置id,那么最终将得到重复的id,这对您没有任何帮助

    如果不知道为什么要显式设置ID,就很难找到解决方法。如果是JavaScript,您可以按照Grant Wagner的建议进行操作,并让JSF将其作为id提供给您。您还可以查看生成的HTML并查看id的格式。JSF通常使用

    "form_id:loop_id:loop_index:component_id" 
    
    作为它为form/repeat中的组件生成的id。您必须确保并为表单和ui提供id:重复标记以了解它们是什么

    好的,您回答说您希望在循环中为特定的inputText设置一个h:message标记,这很简单

    <h:inputText id="myInput" .... />
    <h:message for="myInput" ... />
    
    
    
    现在,为输入生成的消息将显示在消息中,JSF将破坏“for”属性(尽管它不会生成HTML),就像它将破坏inputText中的“id”属性一样,以便它们匹配


    您甚至可以在处理程序代码中生成自己的消息,以转到特定的h:message,但是您需要使用对clientId的调用来获取消息的目标,因为有问题的组件的支持bean(而不是值backingbean)

    您尝试过使用facelets吗

    这将允许您分配自己的ID,即:

    me:labelKeyThingo然后可以使用id=#{labelKey}来创建一个唯一的标签。下面是一个名为m:textPassword的facelet示例,来自我的坏代码:

       <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
        xmlns:c="http://java.sun.com/jstl/core" xmlns:a4j="http://richfaces.org/a4j"
        xmlns:rich="http://richfaces.org/rich">
    
       <ui:composition>
    
        <c:set var="styleClass" value="formPrompt" />
        <c:set var="requiredLabel" value="" />
        <c:choose>
            <c:when test="${required=='true'}">
    
                <c:set var="required" value="true" />
                <c:set var="styleClass" value="formRequiredPrompt" />
                <c:set var="requiredLabel" value="*" />
            </c:when>
        </c:choose>
    
        <h:panelGroup id="#{id}_formRowTemplateLabel_panelGroup">
            <h:outputLabel for="#{id}" styleClass="#{styleClass}" id="#{id}_formRowTemplate_outPut"
                value="#{label}" />
            <c:if test="${required == 'true'}">
                <h:outputText value="#{requiredLabel}" styleClass="formRequiredPromptAsterix"></h:outputText>
            </c:if>
        </h:panelGroup>
    
        <h:panelGroup id="#{id}_textPasswordTemplate_panelGroup">
            <h:inputSecret required="${required}" id="#{id}" value="#{property}"
                styleClass="formText">
    
                <f:validator validatorId="Maserati.Password" />
                <f:validateLength maximum="16" minimum="8" />
                <ui:insert name="additionalTags"></ui:insert>
            </h:inputSecret>
    
            <h:message styleClass="formErrorMsg" id="#{id}_textPasswordTemplate_msg" for="#{id}" />
        </h:panelGroup>
    
       </ui:composition>
    
       </html>
    
    
    
    它的用法如下:

     <m:textPassword id="password" label="#{msgs.passwordPrompt}"
     property="#{individualApplicationMBean.password}"
     required="true" maxlength="16" />
    
    
    
    Whoops。我将此保留了一段时间,不是吗?我理解为什么我不能在循环中分配ID,但我知道我正在设置什么,因为ID(labelKey)对于循环中的每个迭代都是唯一的。至于我想要实现什么,我想知道一种方法,我可以在循环中将h:inputText&h:message链接在一起。因此,如果输入文本的某些验证失败,我可以在它的相关消息框中找到一个错误。我想我可能需要用另一种方式来做,只需要为下拉更改中显示/生成的所有字段提供一条通用消息。很抱歉出现了多条评论-无法将其全部放入300个字符中!哦这就是为什么h:message有一个“for”属性。我将修改我的答案。我有一个相同的问题。你的回答并不能直接解决这个问题,但它给了我一个有用的提示。有时候,即使是一个暗示也能挽救生命。谢谢;)
       <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
        xmlns:c="http://java.sun.com/jstl/core" xmlns:a4j="http://richfaces.org/a4j"
        xmlns:rich="http://richfaces.org/rich">
    
       <ui:composition>
    
        <c:set var="styleClass" value="formPrompt" />
        <c:set var="requiredLabel" value="" />
        <c:choose>
            <c:when test="${required=='true'}">
    
                <c:set var="required" value="true" />
                <c:set var="styleClass" value="formRequiredPrompt" />
                <c:set var="requiredLabel" value="*" />
            </c:when>
        </c:choose>
    
        <h:panelGroup id="#{id}_formRowTemplateLabel_panelGroup">
            <h:outputLabel for="#{id}" styleClass="#{styleClass}" id="#{id}_formRowTemplate_outPut"
                value="#{label}" />
            <c:if test="${required == 'true'}">
                <h:outputText value="#{requiredLabel}" styleClass="formRequiredPromptAsterix"></h:outputText>
            </c:if>
        </h:panelGroup>
    
        <h:panelGroup id="#{id}_textPasswordTemplate_panelGroup">
            <h:inputSecret required="${required}" id="#{id}" value="#{property}"
                styleClass="formText">
    
                <f:validator validatorId="Maserati.Password" />
                <f:validateLength maximum="16" minimum="8" />
                <ui:insert name="additionalTags"></ui:insert>
            </h:inputSecret>
    
            <h:message styleClass="formErrorMsg" id="#{id}_textPasswordTemplate_msg" for="#{id}" />
        </h:panelGroup>
    
       </ui:composition>
    
       </html>
    
     <m:textPassword id="password" label="#{msgs.passwordPrompt}"
     property="#{individualApplicationMBean.password}"
     required="true" maxlength="16" />