JSF 2.0验证和字段突出显示

时间:2012-03-30 09:38:44

标签: java jsf-2 bean-validation

我正在寻找关于在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的示例,我需要将所有组件添加到List中,然后将此列表传递给突出显示方法。如果我使用样式方法,我不必担心组件列表并转到突出显示方法。这对我来说似乎是更好的方法,但是我有点担心它是在JSF页面添加逻辑,这是我想远离的东西。

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

1 个答案:

答案 0 :(得分:0)

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

  

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

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