xPages使用条件自定义验证

时间:2013-09-07 14:14:25

标签: validation xpages serverside-javascript

我不知道在过去的帖子中是否已经讨论过这个问题,但是我找不到类似的内容,所以我的问题就出现了:我在自定义控件上有14个字段。现在在工作流程中的特定条件下,我需要确保应该需要前6个字段(可以通过使用所需的验证器来完成),并且在其他8个字段中,用户应该被强制输入至少2个字段。我怎样才能做到这一点?我对所有字段使用服务器端验证,并将属性“disableClientSideValidation”设置为true。我不确定在这种情况下是否可以使用自定义验证器,如果是,那么如何使用?

2 个答案:

答案 0 :(得分:4)

在您的情况下,您将使用validateExpression。 SSJS代码必须返回true或false。在代码中,您可以使用getComponent("otherFieldName").getSubmittedValue()访问其他字段,并以此方式测试填充的字段数。如果0或1返回false,则返回true。

仅当字段不为空时才会执行validateExpression。因此,将validationExpression添加到前6个必填字段中的一个,并添加validateRequired

示例:

 <xp:inputText
    id="inputRequired1"
    value="#{...}"
    disableClientSideValidation="true">
    <xp:this.validators>
        <xp:validateRequired message="field is required"></xp:validateRequired>
        <xp:validateExpression message="please, fill at least two fields">
            <xp:this.expression><![CDATA[#{javascript:
            num = 0;
            for (i = 1; i <= 8; i++) {
                if (getComponent("inputText" + i).getSubmittedValue() !== "") {
                    num++;
                }
            }
            if (num < 2) {
                return false;
            }
            return true}]]></xp:this.expression>
        </xp:validateExpression>
    </xp:this.validators>
 </xp:inputText>
 <xp:inputText
    id="inputText1"
    value="#{...}">
 </xp:inputText>
 <xp:inputText
    id="inputText2"
    value="#{...}">
 </xp:inputText>
 ... 

答案 1 :(得分:1)

上面提到的解决方案是获取验证句柄的一种方法(有很多),但我认为这不是最佳解决方案,因为您必须在每个输入控件中验证和编写代码。 如果你想要你可以按我的方式去做,但是你必须重做你的验证并将它们全部放在一个ssjs函数中,这最终更容易控制。我已经把示例代码,这显然不完美,旨在快速显示我的意思。如果你选择这样,我建议你包装你的功能,尽可能让它们动态。所以回答这个问题。验证ssjs函数是根据业务逻辑调整验证的地方。

  1. 提交表单时使用操作组。

    <xp:eventHandler id="ehButtonSave"
        refreshMode="partial" submit="true" event="onclick"
        refreshId="somePanelId" >
    
        <xp:this.action>
            <xp:actionGroup>
                <xp:this.condition>
                    <!-- here you validate your fields. Look at number 2 for example -->
                    <!-- this validation function must return true or false which defines if the rest of the code in action group will be executed and the form submitted-->
                    <![CDATA[{javascript:validate("componentValidationErrorDsp");}]]>
                </xp:this.condition>
                <xp:executeScript>
                    <xp:this.script>
                        <![CDATA[#{javascript:
                            <!-- here you can do something with your document -->
                            someSSJSFunction(document1.getDocument());
                        }]]>
                    </xp:this.script>
                </xp:executeScript>
    
                <xp:save></xp:save>
    
            </xp:actionGroup>
        </xp:this.action>
    
        <xp:this.onComplete>
            <![CDATA[XSP.partialRefreshPost('#{id:someInnerPanelId}',{})    ;]]>
        </xp:this.onComplete>
    </xp:eventHandler>
    
  2. 验证示例

    var validate = function(dspErrControlName){
    
        var dspErrControl = getComponent( dspErrControlName);
        var inputField = getComponent("InputText1");
        if(isEmpty(inputField.getValue()){
            // here is where you push the validation message back to the displayErrors xsp control.
            var msgObj = new javax.faces.application.FacesMessage(javax.faces.application.FacesMessage.SEVERITY_ERROR, "validation message", "validation message");
            facesContext.addMessage(dspErrControl.getClientId(facesContext), msgObj);
    
            //and here is a little trick to color your inputs so the user can see where exactly is the problem. 
            //What you do is you set the attribute aria-invalid of the input text component to true. Which you can handle with your CSS to become red or something. 
            //CSS example: [aria-invalid=true] { background-color: #fee; border-color: red; }
            var inpuId=getClientId("InputText1");
            view.postScript("dojo.attr(dojo.byId('"+inputId+"'), 'aria-invalid', 'true');")
        }
    }