为 xPage 表单提交组合服务器端和客户端事件处理程序

Combining server and client side event handlers for xPage Form Submission

我一直在查看在线帖子以及 IBM 的帖子,但我仍然对如何提交表单感到困惑。

我正在使用 formvalidation.io 验证,我从 CSJS 得知验证是否正确。然后,对了就投,不对就不投。

我尝试了不同的变体,但得到了相同的结果。如果验证不正确,表单将继续正确显示并且不会提交。但是,如果验证正确,则不会提交表单。我收到错误消息 XSP.executeOnServer is not a function 并尝试了多种方法来解决此问题,但均未成功。这是我的代码:

<xp:button value="Join Our Team" id="button1">
   <xp:eventHandler event="onclick" submit="false">
      <xp:this.script><![CDATA[$(document).ready(function() {
         $(this).click(function(){
         $("form").data('formValidation').validate();
         var isValidForm = $("form").data('formValidation').isValid();
         if (isValidForm){
            XSP.executeOnServer('#{id:eventhandler1a}', '#{id:panel1}');
         }
         else {
            $("form").data('formValidation').validate();
            return false;
         }
     });
});]]></xp:this.script>

<xp:this.action><![CDATA[#{javascript:XSP.executeOnServer = function () {
// the event handler id to be executed is the first argument, and is required
    if (!arguments[0])
        return false;
    var functionName = arguments[0];

// OPTIONAL - The Client Side ID that is partially refreshed after executing the event handler
    var refreshId = (arguments[1]) ? arguments[1] : "@none";
    var form = (arguments[1]) ? XSP.findForm(arguments[1]) : dojo.query('form')[0];

// catch all in case dojo element has moved object outside of form...
    if (!form)
        form = dojo.query('form')[0];

// OPTIONAL - Options object containing onStart, onComplete and onError functions for the call to the
    // handler and subsequent partial refresh
    var options = (arguments[2]) ? arguments[2] : {};

// OPTIONAL - Value to submit in $$xspsubmitvalue. can be retrieved using context.getSubmittedValue()
    var submitValue = (arguments[3]) ? arguments[3] : '';

// Set the ID in $$xspsubmitid of the event handler to execute
    dojo.query('[name="$$xspsubmitid"]')[0].value = functionName;
    dojo.query('[name="$$xspsubmitvalue"]')[0].value = submitValue;
    this._partialRefresh("post", form, refreshId, options);
}   }]]></xp:this.action>
    </xp:eventHandler>
</xp:button>

<xp:panel id="panel1">
    <xp:eventHandler event="onClick" submit="true" id="eventhandler1a" refreshMode="complete">
    <xp:this.action>
        <xp:saveDocument></xp:saveDocument>
    </xp:this.action>
</xp:eventHandler>
    </xp:panel>

我认为你最好的选择是使用 RPC,它将处理 CS 和 return 一个 go/no-go 值给你的 SSJS 是否提交。下面是一个完整的 XPage,您可以使用它来了解它是如何工作的。这只是填充了一个 viewScope,但我认为它将以一种非常简单的方式向您展示它是如何工作的。

    <?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex">
    <xp:br></xp:br><xp:br></xp:br>
 <xp:button value="CSJS"  id="button2">
    <xp:eventHandler event="onclick" submit="false">
        <xp:this.script><![CDATA[myRPC.myMethod("somevalue").addCallback(function(response) {
    alert("the response is " + response);
});]]></xp:this.script>
    </xp:eventHandler></xp:button>

  <xp:br></xp:br><xp:br></xp:br><xp:br></xp:br><xp:br></xp:br><xp:br></xp:br><xp:br></xp:br>
    <xe:jsonRpcService id="jsonRpcService1" serviceName="myRPC"
    state="true">
    <xe:this.methods>
      <xe:remoteMethod name="myMethod">
        <xe:this.arguments>
            <xe:remoteMethodArg name="myArg" type="string"></xe:remoteMethodArg>
        </xe:this.arguments>
        <xe:this.script>
            <![CDATA[
            print("invocation: " + myArg);
            viewScope.invokedBy = myArg;
            print("viewScope:" + viewScope.invokedBy);
            return viewScope.invokedBy;

          ]]>
        </xe:this.script>
      </xe:remoteMethod>
    </xe:this.methods>
  </xe:jsonRpcService>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:text escape="true" id="computedField1" value="#{viewScope.invokedBy}"></xp:text>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:br></xp:br>
    <xp:button value="Refresh" id="button1">
        <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
            <xp:this.action>
                <xp:confirm>
                    <xp:this.message><![CDATA[#{javascript:return "is: " + viewScope.invokedBy;}]]></xp:this.message>
                </xp:confirm>
            </xp:this.action></xp:eventHandler></xp:button>
    <xp:br></xp:br>
    <xp:br></xp:br></xp:view>

如果事件处理程序中的 CSJS return为真,SSJS 将触发。如果 return 为假,则不会。所以 this.script 只需要 return 为真。

但是,您随后在 this.action 中发布了 CSJS。 eventHandler 的 属性 采用 SSJS,因此 dojo.queryXSP.findForm 将不起作用。您需要将 SSJS 放在那里以保存您的文档或您需要做的任何其他事情。

这是 Domino 不时发生的怪异事件之一。现在我的代码使用简单的 return true 或 return false。我一开始就这样做了,这真是令人头疼,为什么它不起作用。我在使用 Domino 时时常遇到这类事情,当您不知道为什么会发生时,这总是很可怕。但我很高兴我干净、简单的代码现在可以工作了。