【问题标题】:Why the form id prefix in the h:message output?为什么在 h:message 输出中使用表单 id 前缀?
【发布时间】:2011-05-22 01:41:50
【问题描述】:

我目前正在尝试使用 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:Password: Validation Error: Value is required.

这是我的预期,但我不想显示“j_idt7:”的表单 id 前缀。我阅读书籍示例,它们不输出表单 id 前缀。我想要的是:

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

我应该怎么做才能跳过在组件特定消息中显示表单 ID 前缀?

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

【问题讨论】:

  • 谢谢大家的建议,使用 prependId 可以解决我的问题。但我注意到覆盖该必需条目的消息属性:“javax.faces.component.UIInput.REQUIRED={0}:验证错误:需要值。”不会解决问题,因为在我的情况下 {0} 的值是 j_idt7:UserId。所以要么我按照建议的形式给出了一个有意义的 id,要么使用 prependId 解决方案。谢谢!
  • 抱歉,将我的方法更改为使用标签属性的新建议。这样,我的错误消息将在错误消息中显示人性化的名称,而不是字段 ID。
  • 有点晚了:您现在可以为此目的使用requiredMessage

标签: forms validation jsf messages prefix


【解决方案1】:

消息标签默认为组件的客户端 ID,正如您在通过右键单击生成的 HTML 输出中看到的那样,查看源代码。在这种特殊情况下,j_id7 是父 &lt;form&gt; 元素的客户端 ID。如果你给 JSF 组件一个固定的 ID,比如&lt;h:form id="login"&gt;,那么标签将分别变成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,那么你可以使用&lt;o:outputLabel&gt;让JSF透明地设置关联组件的label属性:

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

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

【讨论】:

    【解决方案2】:

    如果您使用 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

    【讨论】:

    • 这违背了 OP 在消息中显示输入字段 ID/标签的要求。
    【解决方案3】:

    您需要从 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

    【讨论】:

      【解决方案4】:

      如果您想从浏览器中查看 HTML 源代码,您会发现 input 字段的 id&lt;form-id&gt;+":"+&lt;input-field-id&gt;,在您的情况下是 j_idt7:UserId:。尝试给你的&lt;h:form&gt; 一些有意义的id 以便从中理解。您可以阅读有关JSF IDs here 的信息。如果你不喜欢它,你可以通过修改你的form标签来关闭它,

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

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

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

      【讨论】:

        【解决方案5】:

        在你写required = true的地方,你可以为任何输入类型定义requiredMessage = "My Message"

        例如

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-30
          相关资源
          最近更新 更多