【问题标题】:JSF 2.0 validation and field highlightingJSF 2.0 验证和字段突出显示
【发布时间】:2012-04-13 23:47:56
【问题描述】:

我正在寻找有关在 JSF 2.0 中添加字段错误突出显示的最佳方式的指导/意见。到目前为止,我已经成功地使用Cagatay's example 实现了一些小的逻辑调整。

String styleClass = ( String ) uiInput.getAttributes().get("styleClass");
        //Check the valid flag
        if ( !uiInput.isValid() )
        {
            //Component already has a styleclass
            if ( styleClass != null )
            {
                //check if it's already highlighted
                if ( !styleClass.contains("ui-input-invalid") )
                {
                    //if not add the error class to it
                    styleClass = styleClass + " ui-input-invalid";
                    //and put the new styleclass back on the component
                    uiInput.getAttributes().put("styleClass", styleClass);
                }
            } else
            {
                //no current style class so just add the error class
                uiInput.getAttributes().put("styleClass", "ui-input-invalid");
            }       
        } else  //component is valid so we might need to remove a highlight
        {
            //component has a styleclass
            if ( styleClass != null )
            {
                //check if it is already highlighted
                if ( styleClass.contains("ui-input-invalid") )
                {
                    //remove error class from the string
                    styleClass = styleClass.replace("ui-input-invalid", "");
                    //and put the new styleclass back on the component
                    uiInput.getAttributes().put("styleClass", styleClass);
                }
            }    
        }

我还使用了将 el 添加到每个组件的样式类的建议 - styleClass="#{component.valid ? '' : 'ui-input-invalid'}"。
当与 Bean Validation JSR303 结合使用时,这两种方法都非常有效。但是,我还有 2 个额外的验证阶段。 1 验证整个表单,即字段的正确组合,1 验证字段和表单验证成功后的一般业务规则。为了让这些阶段也添加突出显示,我需要做一些手动工作。对于这两种突出显示的方法,我必须手动将组件有效标志设置为 false。为了访问该组件,我将它绑定到它自己的对象,格式为 vo。现在对于 Cagatay 的示例,我需要将所有组件添加到列表中,然后将此列表传递给突出显示方法。如果我使用 styleclass 方法,我不必担心组件列表和传递给突出显示的方法。这对我来说似乎是更好的方法,但我有点担心它会向 JSF 页面添加逻辑,这是我想远离的。

您认为最好的方法是什么,或者还有其他我不知道的方法吗?另外我假设没有其他方法可以在不绑定到组件的情况下设置有效标志?目前我必须绑定每个组件,以便设置其有效标志。

【问题讨论】:

    标签: java jsf-2 bean-validation


    【解决方案1】:

    我问这个问题已经有一段时间了,与此同时,我们实际上已经在我们的企业应用程序中实现了部分 JSF。突出显示的字段的解决方案非常复杂,为了使其工作、可重用和可定制,它确实必须紧密地适合包含 JSF/输入值对象、相关输入字段对象和 Bean 验证的框架。因此,在这里磕磕绊绊的人可能无法得到他们正在寻找的答案。但是,我将包含我们内部设计文档的一部分,其中描述了该机制。希望这对其他人有帮助:

    字段突出显示和错误消息 JSF 中的字段突出显示 事实证明这是一项相当复杂的任务。这是因为 html id/name 由 jsf 在运行时生成,可以包含很多前缀。 JSF 会在 id 位于 表单/选项卡/数据表/复合组件。一个 ucn 的 id 可能会结束 成为 tab1:contentForm:jsfDataTable:1:ucn。因此是 几乎不可能尝试预先确定 id 将是什么,并且 然后尝试突出显示。要解决此问题 使用 preRenderComponentEventListener 类。这是注册在 facesConfig.xml 以及输入类型。这告诉 JSF 每当该类型的输入即将出现时运行此类的生命周期 呈现。然后我们可以访问输入的短 id 和长 id 然后我们可以保存并稍后查找。完整程序如下 如下:

    1. facesConfig.xml 中的条目注册了一个 preRenderComponentEventListener 和相关的输入类型。 每次在呈现输入之前,processEvent 方法都是 叫。
    2. facesConfig.xml 中的条目注册了一个名为 componentMap 用于存储输入 id。
    3. 当 调用 processEvent 方法检索 Input 元素。这 检索 componentMap 并将输入的 id/clientID 添加到地图中。 输入的 id 是 Key(这是短 id,即 ucn)和 ClientID 是值(这是长 JSF 生成的 id,即 csn01Form:jsf454:ucn:1)。处理同名的多个输入 就像在 DataTables 中一样,键被添加了一个递增索引。例如。 如果 ucn3 已经在地图中,那么我们将添加 ucn4。
    4. 一旦这个 过程完成后,componentMap 将包含每个条目 输入字段。因此,通过使用短 id,完整的 clientID 可以是 取回。
    5. 在 BackingBean FormatValidationExceptions 和 RuleExceptions 被捕获和处理。
    6. 格式验证异常。这些派生自 BeanValidation。一种 InputVO 的子类被创建,其中包含 Destin8Input(见 CSN01InputVO)。如果需要格式验证 输入它们应该使用自定义 bean 验证进行注释。例如。 @StringCheck(请参阅 Bean 验证)。
    7. FormatValidation 类 有一个名为 validateFormats 的方法,它接受一种 InputVO 并通过 Bean Validator 运行它(使用事务时 控制器会自动运行此方法)。 Bean 验证器 将自动获取每个带注释的字段并运行 isValid() 与注解关联的方法。例如@StringCheck 检查输入的值是否与正则表达式匹配,并且 输入的字符数正确。任何失败都会导致 违反约束。此时生成错误信息 使用来自 Destin8Input 的错误显示名称。所有验证 执行检查并将导致一组 ConstraintViolations。
    8. 在 validateFormats 方法中,ConstraintViolations 集是 循环,每条消息都被添加到错误消息列表中 验证格式异常。每个出错的 htmlID 也会被添加到 字段错误列表。
    9. ValidationFormatException 在 支持豆。所有错误消息都作为 FacesMessage 添加到 显示在页面顶部。
    10. RuleExceptions 类似 除了要突出显示的消息和字段是手动添加时 抛出异常。消息代码将从 D B。
    11. 错误的 id 列表现在循环并用于 从 componentMap 中检索关联的完整 ClientID。每个 ClientID 被添加到列表中。
    12. 此列表被传递给 JSFUtils.highlightFields 方法,其中每个 ClientID 被添加到 ~ 分隔字符串。
    13. 然后将此分隔字符串添加到 RequestMap 键为“errors”(这是一个自动映射 可根据每个请求提供)。
    14. 然后检索此字符串 作为 Destin8Template.xhtml 的一部分 -
    15. 一个 然后立即调用名为 highlightFields 的 javascript 方法。 这有效地循环通过分隔的字符串,获取完整的 id 然后使用 jQuery 添加 Error css 类。
    16. 重要的是 请注意,Java 输入和 JSF 输入之间的链接是 id。在 为了连接 2 至关重要的是它们具有相同的 ID。这是 通过使用 IDConstants 类实现。这是一个 ENUM 包含不同字段的条目。一个条目也被添加到 IDConstants 托管 bean,允许通过 facelet 进行访问。这是 然后添加为适用输入元素的 id 属性。

    【讨论】:

    • Prime Faces 默认会这样做
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2012-02-17
    相关资源
    最近更新 更多