我正在研究的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>
有谁知道我怎么能超越这个?
答案 0 :(得分:8)
你知道他们为什么不让你设置ID,对吗? JSF接管id创建,因为你在重复的组件循环中,如果他们让你只设置id,你最终会得到重复的ID,这对你无论如何都无济于事。
在不知道您为什么要明确设置ID的情况下,很难为您提供解决方法。如果是JavaScript,你可以做Grant Wagner所建议的,让JSF给你它作为id的内容。您还可以查看生成的HTML并查看id的格式.JSF通常使用
"form_id:loop_id:loop_index:component_id"
作为为表单/重复中的组件生成的id。您必须确定并为您的表单提供id和ui:重复标记以了解它们是什么。
好的,你回答说你想在循环中为特定的inputText设置一个h:message标签,这很容易。
<h:inputText id="myInput" .... />
<h:message for="myInput" ... />
现在,为输入生成的消息将显示在消息中,而JSF将破坏“for”属性(虽然这不是生成HTML)就像它将是inputText中的“id”属性所以它们匹配。
您甚至可以在处理程序代码中使用OWN消息转到特定的h:消息,但是在给定支持bean(而不是值)的情况下,您需要使用对clientId的调用来获取消息的目标支持有问题的组件。
答案 1 :(得分: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());
}
希望有所帮助。
答案 2 :(得分: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" />