XPages SSJS 操作组
XPages SSJS Action Group
我有一个点击按钮的动作组。第一个动作,做一些验证,第二个动作抛出一个确认(你想保存吗?)如果是,第三个动作开始并做一些其他的事情。
我遇到的问题是,如果第一个操作验证失败,我不希望其他 2 个操作 运行,所以我应该不会得到确认等。
如果验证失败,我尝试过中断和 return 错误,但似乎都不起作用。我确定我遗漏了一些明显的东西,并且患有星期一综合症,但我似乎无法解决!
下面是事件处理程序代码,谢谢:
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:for (var i = 1; i < viewScope.rows+1; i++) {
print("Starting Array.....");
var fieldName:string = "ObjectiveSelfAssessment" +i;
var fieldName2:string = "ObjectiveDetails" +i;
print ("Field Name: " + fieldName);
var fieldValue = document1.getItemValueString(fieldName);
var fieldValue2 = document1.getItemValueString(fieldName2);
print ("Field Value: " + fieldValue);
if (fieldValue =="" || fieldValue==null){
print("Assessment Empty");
if(!fieldValue2 =="" || !fieldValue2 == null){
print("Objective Empty");
//Do validation
var o = {};
o.title = "Validation Failed";
o.body = "You must enter self assessment details for each objective";
o.alertIcon = "fa-thumbs-down fa-lg";
o.autoClose = true;
o.alertType = "danger";
requestScope.put("alertServer",o);
//requestScope.put("validated",false);
return false;
break;
}
}
}
}]]></xp:this.script>
</xp:executeScript>
<xp:confirm>
<xp:this.message><![CDATA[#{javascript:"Are you sure you want to submit your self assessment?"}]]></xp:this.message>
</xp:confirm>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:document1.replaceItemValue("rows",viewScope.rows);
//document1.replaceItemValue("status","Self Assessment Completed");
document1.save();
var o = {};
o.title = "Document Saved";
o.body = "This document has been succesfully submitted";
o.alertIcon = "fa-thumbs-up fa-lg";
o.autoClose = true;
o.alertType = "success";
requestScope.put("alertServer",o);
}]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
更新 1:操作组的条件代码:
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:this.condition><![CDATA[#{javascript:for (var i = 1; i < viewScope.rows+1; i++) {
print("Starting Array.....");
var fieldName:string = "ObjectiveSelfAssessment" +i;
var fieldName2:string = "ObjectiveDetails" +i;
print ("Field Name: " + fieldName);
var fieldValue = document1.getItemValueString(fieldName);
var fieldValue2 = document1.getItemValueString(fieldName2);
print ("Field Value: " + fieldValue);
if (fieldValue =="" || fieldValue==null){
print("Assessment Empty");
if(!fieldValue2 =="" || !fieldValue2 == null){
print("Objective Empty");
var o = {};
o.title = "Validation Failed";
o.body = "You must enter self assessment details for each objective";
o.alertIcon = "fa-thumbs-down fa-lg";
o.autoClose = true;
o.alertType = "danger";
requestScope.put("alertServer",o);
print("FALSE");
return false;
break;
}else{
print("TRUE");
return true;
}
}
}
}]]></xp:this.condition>
<xp:confirm>
<xp:this.message><![CDATA[#{javascript:"Test11111"}]]></xp:this.message>
</xp:confirm>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:document1.replaceItemValue("rows",viewScope.rows);
//document1.replaceItemValue("status","Self Assessment Completed");
document1.save();
var o = {};
o.title = "Document Saved";
o.body = "This document has been succesfully submitted";
o.alertIcon = "fa-thumbs-up fa-lg";
o.autoClose = true;
o.alertType = "success";
requestScope.put("alertServer",o);}]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action></xp:eventHandler>
您可以向您的 actionGroup 添加条件。这是一个简单的例子:
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup condition="#{javascript:myCondition()}">
xp:confirm>
<xp:this.message><![CDATA[#{javascript:"Are you sure you want to submit your self assessment?"}]]></xp:this.message>
</xp:confirm>
<xp:executeScript>
...
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
因此,在您的情况下,您只需将第一个操作添加为条件,并根据操作组中的逻辑是否必须 运行 将其设为 return true 或 false。
操作组对于基本的、最少编码的操作很有用。但是,如您所见,"easier" 点击式、配置驱动的操作意味着灵活性更难。手动编码可能看起来更难,但更容易实现灵活性。如果您在 XPage 上放置确认操作、预览它并查看源代码,它会告诉您手动编码需要使用什么功能。大约七年前,当我查看 XSP class 时,我认为所使用的函数 XSP.confirm()
相当于基本的 JavaScript confirm()
调用。使用它可以使您的代码更具可读性并使灵活性更容易。
有一个解决方案,但它涉及实施一系列元素以正确支持这种情况。但是当它启动时,我相信它会非常有帮助。
您的问题与 blog post of mine 有点相关。
为了在您的具体情况下为您提供帮助,我将尝试在此处总结所有活动部分。希望你喜欢阅读...
第一个元素:一个server-side辅助方法
如果您在验证阶段之外进行验证,则没有真正的方法让客户知道出了什么问题,或者更好的是可能会发生这种情况,但它会与您想要保留的最终流程断开连接(您的情况) .因此,您首先要做的是创建一种方式来告诉客户。首先我们用一个简单的辅助方法构建一个静态 class:
public enum Helper {
;
public static void setErrorHeader(HttpServletResponse response, PhaseId phaseId) {
response.setHeader("Application-Error", phaseId.toString());
}
}
稍后我们将调用此方法来"flag"验证失败
第二个元素:一个client-side辅助方法
我们需要一个 Java 脚本函数来帮助我们利用最终添加的响应 header(通过 JS 库将此函数添加到您的 XPages)。
var helper = {
isBadRequest : function(xhr) {
return xhr.getResponseHeader("Application-Error") !== null;
}
}
第三个元素:增强的事件处理程序
为了以正确的方式开始工作,我们必须利用事件处理程序参数:
<xp:button id="myButton" value="Three-step action">
<xp:eventHandler
id="myEventHandlerId"
event="onclick"
submit="false"
action="#{myBean.makeItFlow}"
script="threeStep('validate', 'threeStepSave(arguments[1].xhr)')"/>
</xp:button>
eventHandler
具有如上定义的属性非常重要:
id
: 用于稍后抓取事件处理程序
submit="false"
: 不提交表单,我们将手动提交
action
:包含对将被调用的服务器端 bean 方法的引用。我使用了名字 myBean.makeItFlow
。我假设您知道如何使用托管 beans
script
:"real" 动作发生的地方
此时在脚本属性中我们调用执行 post - XSP.partialRefreshPost()
的 XPages client-side javascript 方法 - 我们手动传递各种参数。在这种情况下,我选择避免将所有必要的脚本 in-line 与事件放在一起。您可以在页面底部添加以下辅助函数:
<xp:scriptBlock
value="
function threeStep(param, onCompleteFunc) {
var execId = '#{id:containerId}';
var refreshId = '#{id:containerId}';
var eventHandlerId = '#{id:myEventHandlerId}';
var opts = {
execId: execId,
params: { '$$xspsubmitid': eventHandlerId, action: param },
onError : 'console.log(arguments[0])'
};
if (onCompleteFunc) {
opts.onComplete = onCompleteFunc;
}
XSP.partialRefreshPost(refreshId, opts);
}
function threeStepSave(xhr) {
if (helper.isBadRequest(xhr)) {
return alert('Validation failed');
}
if (!confirm('Do you want to continue?')) return;
threeStep('save');
}" />
方法的第一个参数是要刷新的id。然后我们有一个 object 其属性定义:
param
:我们要传递的参数以调整 server-side 方法行为
onCompleteFunc
: 客户端javascript 将在服务器端方法评估结束时调用(js 必须是字符串,将被评估)
var execId
:将与 POST 一起提交的块(以及范围)
var refreshId
: 将要刷新的块
var eventHandlerId
:非常重要的事件处理器ID参考
第四要素:bean动作方法
现在,通过 Java bean,我们定义了按钮背后的所有操作逻辑。我决定采用一种特定方法,该方法将对事件处理程序传递的 action
参数值作出反应。
public void makeItFlow() {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String action = (String) externalContext.getRequestParameterMap().get("action");
if ("validate".equals(action)) {
// Your logic
boolean failed = false;
// When validation fails add the error response header
if (failed) {
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
Helper.setErrorHeader(response, PhaseId.INVOKE_APPLICATION);
}
} else if ("save".equals(action)) {
// Let's save this thing
}
}
我正在添加一个关于它应该如何表现的简短视频(在示例中我添加了一些额外的代码以使各个阶段显而易见)
Paul,我已经接受了你的回答,reg 做更多的手动编码,因为这是我采用的方法。我正在提交一个答案,以便我可以使用代码格式来展示我的解决方案....
我现在在客户端进行验证 - 获取子项等的原因是我 create/remove 动态显示字段,这些字段与我的文本框的重复控件一起显示,所以我不知道元素 ID。 ...
var objcolparent = document.getElementById("ObjColOuter").children[0];
var sacolparent = document.getElementById("SAColOuter").children[0];
var rows = sacolparent.getElementsByTagName("TEXTAREA").length;
for (var i = 0; i < rows; i++) {
var saValue = sacolparent.getElementsByTagName("TEXTAREA")[i].value;
if(saValue ==""){
var objValue = objcolparent.getElementsByTagName("TEXTAREA")[i].value;
if(!objValue==""){
// Validation failed, do client side bootalert
var o = {};
o.title = "Validation Failed";
o.body = "You must enter self assessment details for each objective";
o.alertIcon = "fa-thumbs-down fa-lg";
o.alertType = "danger";
bootAlert.show('alertServer',JSON.stringify(o))
return false;
break;
}
}
}
if(confirm("Are you sure you want to submit your self assessment?")){
return true;
}else{
return false;
}
如果验证成功,它会继续 运行 我的服务器端内容:
document1.replaceItemValue("rows",viewScope.rows);
document1.replaceItemValue("status","Self Assessment Completed");
document1.save();
var o = {}
o.title = "Document Saved";
o.body = "This document has been succesfully submitted";
o.alertIcon = "fa-thumbs-up fa-lg";
o.autoClose = true;
o.alertType = "success";
requestScope.put("alertServer",o)
感谢大家的贡献!
我有一个点击按钮的动作组。第一个动作,做一些验证,第二个动作抛出一个确认(你想保存吗?)如果是,第三个动作开始并做一些其他的事情。
我遇到的问题是,如果第一个操作验证失败,我不希望其他 2 个操作 运行,所以我应该不会得到确认等。
如果验证失败,我尝试过中断和 return 错误,但似乎都不起作用。我确定我遗漏了一些明显的东西,并且患有星期一综合症,但我似乎无法解决!
下面是事件处理程序代码,谢谢:
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:for (var i = 1; i < viewScope.rows+1; i++) {
print("Starting Array.....");
var fieldName:string = "ObjectiveSelfAssessment" +i;
var fieldName2:string = "ObjectiveDetails" +i;
print ("Field Name: " + fieldName);
var fieldValue = document1.getItemValueString(fieldName);
var fieldValue2 = document1.getItemValueString(fieldName2);
print ("Field Value: " + fieldValue);
if (fieldValue =="" || fieldValue==null){
print("Assessment Empty");
if(!fieldValue2 =="" || !fieldValue2 == null){
print("Objective Empty");
//Do validation
var o = {};
o.title = "Validation Failed";
o.body = "You must enter self assessment details for each objective";
o.alertIcon = "fa-thumbs-down fa-lg";
o.autoClose = true;
o.alertType = "danger";
requestScope.put("alertServer",o);
//requestScope.put("validated",false);
return false;
break;
}
}
}
}]]></xp:this.script>
</xp:executeScript>
<xp:confirm>
<xp:this.message><![CDATA[#{javascript:"Are you sure you want to submit your self assessment?"}]]></xp:this.message>
</xp:confirm>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:document1.replaceItemValue("rows",viewScope.rows);
//document1.replaceItemValue("status","Self Assessment Completed");
document1.save();
var o = {};
o.title = "Document Saved";
o.body = "This document has been succesfully submitted";
o.alertIcon = "fa-thumbs-up fa-lg";
o.autoClose = true;
o.alertType = "success";
requestScope.put("alertServer",o);
}]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
更新 1:操作组的条件代码:
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup>
<xp:this.condition><![CDATA[#{javascript:for (var i = 1; i < viewScope.rows+1; i++) {
print("Starting Array.....");
var fieldName:string = "ObjectiveSelfAssessment" +i;
var fieldName2:string = "ObjectiveDetails" +i;
print ("Field Name: " + fieldName);
var fieldValue = document1.getItemValueString(fieldName);
var fieldValue2 = document1.getItemValueString(fieldName2);
print ("Field Value: " + fieldValue);
if (fieldValue =="" || fieldValue==null){
print("Assessment Empty");
if(!fieldValue2 =="" || !fieldValue2 == null){
print("Objective Empty");
var o = {};
o.title = "Validation Failed";
o.body = "You must enter self assessment details for each objective";
o.alertIcon = "fa-thumbs-down fa-lg";
o.autoClose = true;
o.alertType = "danger";
requestScope.put("alertServer",o);
print("FALSE");
return false;
break;
}else{
print("TRUE");
return true;
}
}
}
}]]></xp:this.condition>
<xp:confirm>
<xp:this.message><![CDATA[#{javascript:"Test11111"}]]></xp:this.message>
</xp:confirm>
<xp:executeScript>
<xp:this.script><![CDATA[#{javascript:document1.replaceItemValue("rows",viewScope.rows);
//document1.replaceItemValue("status","Self Assessment Completed");
document1.save();
var o = {};
o.title = "Document Saved";
o.body = "This document has been succesfully submitted";
o.alertIcon = "fa-thumbs-up fa-lg";
o.autoClose = true;
o.alertType = "success";
requestScope.put("alertServer",o);}]]></xp:this.script>
</xp:executeScript>
</xp:actionGroup>
</xp:this.action></xp:eventHandler>
您可以向您的 actionGroup 添加条件。这是一个简单的例子:
<xp:eventHandler event="onclick" submit="true" refreshMode="complete">
<xp:this.action>
<xp:actionGroup condition="#{javascript:myCondition()}">
xp:confirm>
<xp:this.message><![CDATA[#{javascript:"Are you sure you want to submit your self assessment?"}]]></xp:this.message>
</xp:confirm>
<xp:executeScript>
...
</xp:executeScript>
</xp:actionGroup>
</xp:this.action>
</xp:eventHandler>
因此,在您的情况下,您只需将第一个操作添加为条件,并根据操作组中的逻辑是否必须 运行 将其设为 return true 或 false。
操作组对于基本的、最少编码的操作很有用。但是,如您所见,"easier" 点击式、配置驱动的操作意味着灵活性更难。手动编码可能看起来更难,但更容易实现灵活性。如果您在 XPage 上放置确认操作、预览它并查看源代码,它会告诉您手动编码需要使用什么功能。大约七年前,当我查看 XSP class 时,我认为所使用的函数 XSP.confirm()
相当于基本的 JavaScript confirm()
调用。使用它可以使您的代码更具可读性并使灵活性更容易。
有一个解决方案,但它涉及实施一系列元素以正确支持这种情况。但是当它启动时,我相信它会非常有帮助。
您的问题与 blog post of mine 有点相关。 为了在您的具体情况下为您提供帮助,我将尝试在此处总结所有活动部分。希望你喜欢阅读...
第一个元素:一个server-side辅助方法
如果您在验证阶段之外进行验证,则没有真正的方法让客户知道出了什么问题,或者更好的是可能会发生这种情况,但它会与您想要保留的最终流程断开连接(您的情况) .因此,您首先要做的是创建一种方式来告诉客户。首先我们用一个简单的辅助方法构建一个静态 class:
public enum Helper {
;
public static void setErrorHeader(HttpServletResponse response, PhaseId phaseId) {
response.setHeader("Application-Error", phaseId.toString());
}
}
稍后我们将调用此方法来"flag"验证失败
第二个元素:一个client-side辅助方法
我们需要一个 Java 脚本函数来帮助我们利用最终添加的响应 header(通过 JS 库将此函数添加到您的 XPages)。
var helper = {
isBadRequest : function(xhr) {
return xhr.getResponseHeader("Application-Error") !== null;
}
}
第三个元素:增强的事件处理程序
为了以正确的方式开始工作,我们必须利用事件处理程序参数:
<xp:button id="myButton" value="Three-step action">
<xp:eventHandler
id="myEventHandlerId"
event="onclick"
submit="false"
action="#{myBean.makeItFlow}"
script="threeStep('validate', 'threeStepSave(arguments[1].xhr)')"/>
</xp:button>
eventHandler
具有如上定义的属性非常重要:
id
: 用于稍后抓取事件处理程序submit="false"
: 不提交表单,我们将手动提交action
:包含对将被调用的服务器端 bean 方法的引用。我使用了名字myBean.makeItFlow
。我假设您知道如何使用托管 beansscript
:"real" 动作发生的地方
此时在脚本属性中我们调用执行 post - XSP.partialRefreshPost()
的 XPages client-side javascript 方法 - 我们手动传递各种参数。在这种情况下,我选择避免将所有必要的脚本 in-line 与事件放在一起。您可以在页面底部添加以下辅助函数:
<xp:scriptBlock
value="
function threeStep(param, onCompleteFunc) {
var execId = '#{id:containerId}';
var refreshId = '#{id:containerId}';
var eventHandlerId = '#{id:myEventHandlerId}';
var opts = {
execId: execId,
params: { '$$xspsubmitid': eventHandlerId, action: param },
onError : 'console.log(arguments[0])'
};
if (onCompleteFunc) {
opts.onComplete = onCompleteFunc;
}
XSP.partialRefreshPost(refreshId, opts);
}
function threeStepSave(xhr) {
if (helper.isBadRequest(xhr)) {
return alert('Validation failed');
}
if (!confirm('Do you want to continue?')) return;
threeStep('save');
}" />
方法的第一个参数是要刷新的id。然后我们有一个 object 其属性定义:
param
:我们要传递的参数以调整 server-side 方法行为onCompleteFunc
: 客户端javascript 将在服务器端方法评估结束时调用(js 必须是字符串,将被评估)var execId
:将与 POST 一起提交的块(以及范围)
var refreshId
: 将要刷新的块var eventHandlerId
:非常重要的事件处理器ID参考
第四要素:bean动作方法
现在,通过 Java bean,我们定义了按钮背后的所有操作逻辑。我决定采用一种特定方法,该方法将对事件处理程序传递的 action
参数值作出反应。
public void makeItFlow() {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
String action = (String) externalContext.getRequestParameterMap().get("action");
if ("validate".equals(action)) {
// Your logic
boolean failed = false;
// When validation fails add the error response header
if (failed) {
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
Helper.setErrorHeader(response, PhaseId.INVOKE_APPLICATION);
}
} else if ("save".equals(action)) {
// Let's save this thing
}
}
我正在添加一个关于它应该如何表现的简短视频(在示例中我添加了一些额外的代码以使各个阶段显而易见)
Paul,我已经接受了你的回答,reg 做更多的手动编码,因为这是我采用的方法。我正在提交一个答案,以便我可以使用代码格式来展示我的解决方案....
我现在在客户端进行验证 - 获取子项等的原因是我 create/remove 动态显示字段,这些字段与我的文本框的重复控件一起显示,所以我不知道元素 ID。 ...
var objcolparent = document.getElementById("ObjColOuter").children[0];
var sacolparent = document.getElementById("SAColOuter").children[0];
var rows = sacolparent.getElementsByTagName("TEXTAREA").length;
for (var i = 0; i < rows; i++) {
var saValue = sacolparent.getElementsByTagName("TEXTAREA")[i].value;
if(saValue ==""){
var objValue = objcolparent.getElementsByTagName("TEXTAREA")[i].value;
if(!objValue==""){
// Validation failed, do client side bootalert
var o = {};
o.title = "Validation Failed";
o.body = "You must enter self assessment details for each objective";
o.alertIcon = "fa-thumbs-down fa-lg";
o.alertType = "danger";
bootAlert.show('alertServer',JSON.stringify(o))
return false;
break;
}
}
}
if(confirm("Are you sure you want to submit your self assessment?")){
return true;
}else{
return false;
}
如果验证成功,它会继续 运行 我的服务器端内容:
document1.replaceItemValue("rows",viewScope.rows);
document1.replaceItemValue("status","Self Assessment Completed");
document1.save();
var o = {}
o.title = "Document Saved";
o.body = "This document has been succesfully submitted";
o.alertIcon = "fa-thumbs-up fa-lg";
o.autoClose = true;
o.alertType = "success";
requestScope.put("alertServer",o)
感谢大家的贡献!