如何仅在点击指定按钮时触发XPages文本域的自定义验证器
问题:仅在特定按钮提交时触发XPages自定义验证器
我给xp:inputTextarea控件配置了验证规则:
<xp:inputTextarea id="inpRelPresentation" value="#{matterBean.matter.busRelations}" validator="#{matterValidators.valBusinessRelation}"> <xp:this.validators> <xp:validateRequired> <xp:this.message><![CDATA[#{javascript:xptI18NBean.getValue("matter.msg_valid_business_relation")}]]></xp:this.message> </xp:validateRequired> </xp:this.validators> <xp:this.required><![CDATA[#{javascript:return ( submittedBy('btnSendToCommitee'))}]]></xp:this.required> </xp:inputTextarea>
其中required属性仅在点击ID为btnSendToCommittee的按钮时触发检查,但点击Save等其他按钮时,自定义验证器valBusinessRelation仍会被调用。
自定义验证器代码如下:
public void valBusinessRelation(FacesContext context, UIComponent component, Object value) throws ValidatorException { System.out.println("start valBusinessRelation"); if (value == null || StringUtil.isEmpty((String) value)) { System.out.println("do a return"); return; } String trimmed = ((String) value).trim(); if (trimmed.toString().replaceAll("\s+","").equals("")){ System.out.println("empty after trimming etc, throw validator exception"); String msgTxt = langBean.getValue("matter.msg_valid_business_relation"); FacesMessage msg = new FacesMessage(msgTxt, msgTxt); msg.setSeverity(FacesMessage.SEVERITY_ERROR); throw new ValidatorException(msg); } }
需要让该自定义验证器仅在点击btnSendToCommittee按钮时被调用,但submittedBy('btnSendToCommitee')是SSJS检查,验证器调用用的是EL,不知道如何实现,也未找到通过validator-id调用验证器的完整示例。
解决方案1:在Java验证器内部判断提交按钮
直接在验证器逻辑开头检查当前请求是否由目标按钮发起,非目标按钮提交则跳过验证。
修改后的Java验证器代码:
public void valBusinessRelation(FacesContext context, UIComponent component, Object value) throws ValidatorException { // 检查请求是否来自目标按钮(注意:若按钮在命名容器内,需使用完整客户端ID) HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); if (!request.getParameterMap().containsKey("btnSendToCommittee")) { return; // 非目标按钮提交,跳过验证 } // 原有验证逻辑 System.out.println("start valBusinessRelation"); if (value == null || StringUtil.isEmpty((String) value)) { System.out.println("do a return"); return; } String trimmed = ((String) value).trim(); if (trimmed.replaceAll("\\s+", "").isEmpty()){ System.out.println("empty after trimming etc, throw validator exception"); String msgTxt = langBean.getValue("matter.msg_valid_business_relation"); FacesMessage msg = new FacesMessage(msgTxt, msgTxt); msg.setSeverity(FacesMessage.SEVERITY_ERROR); throw new ValidatorException(msg); } }
提示:可通过查看页面源码获取按钮的实际客户端ID(若存在命名容器前缀,比如
view:_id1:btnSendToCommittee)。
解决方案2:用SSJS动态调用验证器
将验证器绑定改为SSJS,仅在目标按钮提交时执行验证逻辑,和required属性的判断逻辑保持一致:
修改xp:inputTextarea的validator属性:
<xp:inputTextarea id="inpRelPresentation" value="#{matterBean.matter.busRelations}"> <xp:this.validators> <xp:validateRequired> <xp:this.message><![CDATA[#{javascript:xptI18NBean.getValue("matter.msg_valid_business_relation")}]]></xp:this.message> </xp:validateRequired> </xp:this.validators> <xp:this.required><![CDATA[#{javascript:return ( submittedBy('btnSendToCommitee'))}]]></xp:this.required> <xp:this.validator><![CDATA[#{javascript: if (submittedBy('btnSendToCommitee')) { matterValidators.valBusinessRelation(facesContext, component, value); } }]]></xp:this.validator> </xp:inputTextarea>
这种方式无需处理客户端ID前缀问题,逻辑更直观。
解决方案3:通过validator-id注册并条件渲染
适合需要复用验证器的场景,需先在faces-config.xml注册验证器:
<validator> <validator-id>valBusinessRelation</validator-id> <validator-class>com.yourpackage.ValBusinessRelation</validator-class> </validator>
注意:需将原Bean中的验证方法改为独立的
Validator实现类:public class ValBusinessRelation implements Validator { @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { // 原有验证逻辑 } }
然后在页面中通过xp:validator标签,结合rendered属性控制验证器是否生效:
<xp:inputTextarea id="inpRelPresentation" value="#{matterBean.matter.busRelations}"> <xp:this.validators> <xp:validateRequired> <xp:this.message><![CDATA[#{javascript:xptI18NBean.getValue("matter.msg_valid_business_relation")}]]></xp:this.message> </xp:validateRequired> <xp:validator validatorId="valBusinessRelation" rendered="#{javascript:submittedBy('btnSendToCommitee')}"/> </xp:this.validators> <xp:this.required><![CDATA[#{javascript:return ( submittedBy('btnSendToCommitee'))}]]></xp:this.required> </xp:inputTextarea>
内容的提问来源于stack exchange,提问作者Patrick Kwinten
相关产品推荐
相关产品推荐

