1

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

4

2 回答 2

5

在您的情况下,您将使用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>
 ... 
于 2013-09-07T21:57:30.763 回答
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');")
        }
    }
    
于 2014-01-14T12:47:38.940 回答