5

我正在处理的 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>

有谁知道我怎么能克服这个问题?

4

3 回答 3

8

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

在不知道为什么要显式设置 ID 的情况下,很难为您提供解决方法。如果是 JavaScript,你可以按照 Grant Wagner 的建议去做,让 JSF 给你它作为 id 的内容。您还可以查看生成的 HTML 并查看 id 的格式。JSF 通常使用

"form_id:loop_id:loop_index:component_id" 

作为它为表单/重复中的组件生成的 id。您必须确定并为您的表单和 ui:repeat 标签提供 id 以了解它们是什么。

好的,你回答说你想在循环中为特定的 inputText 有一个 h:message 标记,这很容易。

<h:inputText id="myInput" .... />
<h:message for="myInput" ... />

现在,为输入生成的消息将显示在消息中,并且 JSF 将破坏“for”属性(尽管它不会生成到 HTML),就像它会破坏 inputText 中的“id”属性一样,以便它们匹配。

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

于 2008-11-28T18:32:04.460 回答
3

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

由于您无法通过表达式设置 ID,因此我这样做:

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

然后在后面的代码中:

<script type="text/javascript">
var theElement = document.getElementById('<h:outputText value="#{pagecode.whateverClientId}"/ >');
...
</script>

在页面代码中:

protected HtmlInputText getWhatever() {
    if (whatever == null) {
        whatever = (HtmlInputText) findComponentInRoot("whatever");
    }
}

public String getWhateverClientId() {
    return getWhatever().getClientId(getFacesContext());
}

希望有帮助。

于 2008-11-25T19:07:15.540 回答
0

你试过使用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" />
于 2009-03-19T06:45:57.070 回答