为什么h:message输出中的表单id前缀?

时间:2010-12-08 07:28:12

标签: forms validation jsf messages prefix

我目前正在尝试使用required =“true”进行简单验证

    <h:form>
        <h:messages globalOnly="true"/>
        <h:panelGrid>
            <h:panelGrid columns="3">
                <f:facet name="header">
                    Login Application Sample
                </f:facet>

                <h:outputLabel for="UserId" value="User Id" />
                <h:inputText id="UserId" value="#{userBean.userId}" required="true" />
                <h:message for="UserId"/>

                <h:outputLabel for="Password" value="Password" />
                <h:inputSecret id="Password" value="#{userBean.password}" required="true" />
                <h:message for="Password" />

                <f:facet name="footer">
                    <h:commandButton value="Login" action="#{userBean.login}"/>
                    <h:commandButton type="reset" value="Reset"/>
                </f:facet>
            </h:panelGrid>
        </h:panelGrid>
    </h:form>

将字段留空,然后单击登录按钮,这些错误消息将显示在每个字段的右侧:

  

j_idt7:UserId:验证错误:需要值   j_idt7:密码:验证错误:值是必需的。

这是我的预期,但我不想显示'j_idt7:'的表单id前缀。我读过书中的例子,他们不输出表格id前缀。我想要的是:

  

UserId:验证错误:需要值。
  密码:验证错误:值是必需的。

如何跳过在组件特定消息中显示表单ID前缀?

我目前正在使用glassfish v3测试JSF 2。

5 个答案:

答案 0 :(得分:13)

消息标签默认为组件的客户端ID,正好是您通过右键单击查看源在生成的HTML输出中看到的ID。 j_id7在此特定情况下是父<form>元素的客户端ID。如果您为JSF组件提供固定ID,例如<h:form id="login">,那么标签将分别变为login:UserIdlogin:Password

然而,您可以使用输入组件的label属性完全覆盖它,以便消息标签将完全按照您的意图显示。

<h:inputText ... label="User ID" />
<h:inputSecret ... label="Password" />

如果输入组件的label属性存在,则将使用它来代替客户端ID。根据其他答案的建议使用prependId="false" disadvantages。不要那样做。

完全不同的替代方法是使用requiredMessage(或converterMessagevalidatorMessage)属性,但这不允许参数化消息,因此您必须对其进行硬编码标签等。

<h:inputText ... label="User ID is required." />
<h:inputSecret ... label="Password is required." />

另见:


注意到标签重复的确如此尴尬:

<h:outputLabel for="userId" value="User ID" ... />
<h:inputText id="userId" ... label="User ID" />

<h:outputLabel for="password" value="Password" ... />
<h:inputSecret id="password" ... label="Password" />

如果您碰巧使用JSF实用程序库OmniFaces,那么您可以使用<o:outputLabel>让JSF透明地设置相关组件的label属性:

<o:outputLabel for="userId" value="User ID" ... />
<h:inputText id="userId" ... />

<o:outputLabel for="password" value="Password" ... />
<h:inputSecret id="password" ... />

答案 1 :(得分:5)

如果您使用MyFaces和bean验证框架(JSR303),请尝试使用密钥javax.faces.validator.BeanValidator.MESSAGE定义MessageBundle

faces-config.xml中

<application>
    <message-bundle>ApplicationMessages</message-bundle>
</application>

ApplicationMessages.properties

#javax.faces.validator.BeanValidator.MESSAGE={1}: {0}
javax.faces.validator.BeanValidator.MESSAGE={0}

Details

答案 2 :(得分:2)

您需要从JSF覆盖这些消息。

您可以在类路径中拥有messages.properties文件

Messages.properties

javax.faces.component.UIInput.REQUIRED=Field must be entered.  

Faces-config.xml

<application>
      <message-bundle>Messages</message-bundle>
      <locale-config>
          <default-locale>en</default-locale>

      </locale-config>
  </application>    

Have a look at this Article

答案 3 :(得分:1)

如果您希望从浏览器中看到HTML源代码,您会发现id字段的input<form-id>+":"+<input-field-id>,在您的情况下,j_idt7:UserId: 。尝试为<h:form>提供一些有意义的id,以便从中理解它。你可以阅读JSF IDs here。如果您不喜欢它,可以通过将form标记修改为类似的内容来关闭它,

<h:form prependId = false> // its true by default.

但正如BalusC所指出的那样,这可能会产生问题。

此外,您似乎从未配置过任何验证消息。这反过来最终得到这个消息。因此,需要message.properties文件来控制消息并显示更合适的内容。即使这样,字段名称也不应该是消息的一部分,以使这些验证消息通用以避免重复。有关在label内使用<h:inputText>属性的信息,请参阅BalusC's answer

答案 4 :(得分:1)

您在撰写required = true的位置,可以为任何输入类型定义requiredMessage = "My Message"

e.g。

<h:inputText autocomplete="false" id = "CellNumber" label="Cell Number" required="true" requiredMessage="Cell Number Required" maxlength="10" value="#{userManagedBean.cellNumber}" >