我正在寻找关于在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页面添加逻辑,这是我想远离的东西。
您觉得最好的方法是什么,还是我不知道的另一种方式?另外我假设没有其他方法设置有效标志而不绑定组件?目前我必须绑定每个组件,以便我可以设置其有效标志。
答案 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 然后我们可以保存并稍后查找。完整的程序如下 如下:
- facesConfig.xml中的条目注册了一个 preRenderComponentEventListener和相关的输入类型。 每次在呈现输入之前,processEvent方法都是 调用。
- facesConfig.xml中的条目注册了一个名为的HashMap componentMap,用于存储输入ID。
- 当 调用processEvent方法检索Input元素。该 检索componentMap并将输入的id / clientID添加到地图中。 输入的id是Key(这是短ID,即ucn)和 ClientID是值(这是长JSF生成的id,即 csn01Form:jsf454:UCN:1)。处理同名的多个输入 就像在DataTables中一样,密钥添加了增量索引。例如。 如果ucn3已经在地图中,那么ucn4将会添加。
- 一旦这个 进程完成后,componentMap将包含每个条目 输入字段。因此,通过使用短ID,完整的clientID可以 检索。
- 在BackingBean FormatValidationExceptions和 捕获并处理RuleExceptions。
- FormatValidationExceptions。这些派生自BeanValidation。一个 创建一个InputVO的子类,其中包含的子类 Destin8Input(参见CSN01InputVO)。如果需要格式验证 输入它们应该使用自定义bean验证进行注释。例如。 @StringCheck(参见Bean验证)。
- FormatValidation类 有一个名为validateFormats的方法,它接受一种InputVO 并通过Bean Validator运行它(使用Transaction时) 控制器此方法将自动运行)。 Bean验证器 将自动获取每个带注释的字段并运行isValid() 与注释相关联的方法。以@StringCheck为例 检查输入的值是否与正则表达式匹配 输入的字符数是正确的。任何失败都会导致 ConstraintViolation。此时会生成错误消息 使用Destin8Input中的错误显示名称。所有验证 执行检查并生成一组ConstraintViolations。
- 在validateFormats方法中,ConstraintViolations集是 循环并将每条消息添加到的错误消息列表中 ValidationFormatException。每个错误的htmlID也会添加到a 字段错误列表。
- ValidationFormatException被捕获 BackingBean。所有错误消息都将添加为FacesMessage 显示在页面顶部。
- RuleExceptions类似 除了要突出显示的消息和字段时,手动添加 抛出一个例外。消息代码将从中查找 D B。
- 错误的ID列表现在循环播放并用于 从componentMap中检索关联的完整ClientID。每 ClientID被添加到List中。
- 此列表传递给 JSFUtils.highlightFields方法,其中每个ClientID都添加到〜 分隔字符串。
- 然后将此分隔的String添加到 RequestMap带有'errors'键(这是一张自动映射的地图) 根据每个请求提供)。
- 然后检索此字符串 作为Destin8Template.xhtml -
的一部分- 甲 然后立即调用名为highlightFields的javascript方法。 这有效地循环分隔的String,获取完整的id 然后使用jQuery添加Error css类。
- 重要的是 请注意,Java Input和JSF Input之间的链接是id。在 为了连接2,它们具有相同的ID至关重要。这是 通过使用IDConstants类实现。这是一个ENUM 包含不同字段的条目。一个条目也被添加到 IDConstants托管bean允许通过facelet进行访问。这是 然后添加为适用的输入元素的id属性。
醇>