首页 文章

JSF 2.0验证和字段突出显示

提问于
浏览
2

我正在寻找关于在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 's example I need to add all of the components to a List and then pass this list to the highlighting method. If I use the styleclass approach I don' t不得不担心组件列表并传递给突出显示方法 . 这对我来说似乎是更好的方法,但我有点担心它是在JSF页面添加逻辑,这是我想要远离的东西 .

您认为最好的方法是什么,还是我不知道的另一种方式?另外我假设没有其他方法设置有效标志而不绑定组件?目前我必须绑定每个组件,以便我可以设置其有效标志 .

1 回答

  • 0

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

    字段突出显示和错误消息JSF中的字段突出显示是一项相当复杂的任务 . 这是因为html id / name是由jsf在运行时生成的,可以包含许多前缀 . 当JSF位于表单/ tab / datatable / composite组件中时,它将为id添加前缀 . ucn的id可能最终成为tab1:contentForm:jsfDataTable:1:ucn . 因此,几乎不可能尝试预先确定id将是什么,然后尝试突出显示 . 要解决此问题,请使用preRenderComponentEventListener类 . 这在facesConfig.xml中与输入类型一起注册 . 这告诉JSF生命周期在每次要呈现该类型的输入时运行此类 . 然后我们可以访问输入的短和长ID,然后我们可以保存并稍后查找 . 完整过程如下:facesConfig.xml中的条目注册了preRenderComponentEventListener和相关的输入类型 . 每次在呈现输入之前,都会调用processEvent方法 . facesConfig.xml中的条目注册了一个名为componentMap的HashMap,用于存储输入ID . 调用processEvent方法时,将检索Input元素 . 检索componentMap并将输入的id / clientID添加到 Map 中 . 输入的id是Key(这是短ID,即ucn),ClientID是值(这是长JSF生成的id,即csn01Form:jsf454:ucn:1) . 要处理多个像DataTables一样的同名输入,密钥会添加一个递增索引 . 例如 . 如果ucn3已经在 Map 中,那么ucn4将会添加 . 完成此过程后,componentMap将包含每个输入字段的条目 . 因此,通过使用short id,可以检索完整的clientID . 在BackingBean中捕获并处理FormatValidationExceptions和RuleExceptions . FormatValidationExceptions . 这些派生自BeanValidation . 创建InputVO的子类,其中包含Destin8Input的子类(请参阅CSN01InputVO) . 如果输入上需要格式验证,则应使用自定义bean验证进行注释 . 例如 . @StringCheck(参见Bean验证) . FormatValidation类有一个名为validateFormats的方法,它接受一种InputVO并通过Bean Validator运行它(当使用Transaction Controller时,将自动运行此方法) . Bean Validator将自动获取每个带注释的字段并运行与注释关联的isValid()方法 . 例如,@ StringCheck检查输入的值是否与正则表达式匹配,并且输入的字符数是否正确 . 任何失败都将导致ConstraintViolation . 此时,使用Destin8Input中的错误显示名称生成错误消息 . 将执行所有验证检查,并将生成一组ConstraintViolations . 在validateFormats方法中,Set of ConstraintViolations循环并且添加了每条消息到ValidationFormatException中的错误消息列表 . 每个错误的htmlID也会添加到字段错误列表中 . ValidationFormatException在BackingBean中捕获 . 所有错误消息都将添加为FacesMessage,以显示在页面顶部 . RuleExceptions类似,除了在抛出异常时手动添加要突出显示的消息和字段 . 将从数据库中查找消息代码 . 错误的ID列表现在循环,用于从componentMap检索关联的完整ClientID . 每个ClientID都添加到List中 . 此List传递给JSFUtils.highlightFields方法,其中每个ClientID都添加到~Delimited String . 然后使用“错误”键将此分隔的String添加到RequestMap(这是根据每个请求自动提供的映射) . 然后将此String作为Destin8Template.xhtml的一部分进行检索 - 一个名为highlightFields的javascript方法然后立即被调用 . 这有效地循环分隔的String,获取完整的id,然后使用jQuery添加Error css类 . 值得注意的是,Java Input和JSF Input之间的链接是id . 为了连接2,它们具有相同的ID至关重要 . 这是通过使用IDConstants类实现的 . 这是一个包含不同字段条目的ENUM . IDConstants托管bean还添加了一个条目,允许通过facelet进行访问 . 然后将其添加为适用输入元素的id属性 .

相关问题