这就是我想要做的事情:
在XPage上我想要一个编辑框控件,当用户按下回车键时,它会调用一些服务器端代码(Java bean或SSJS).这个主要用例是这个页面将从iPad上运行,并附带一个蓝牙条码扫描器.此扫描仪模拟键盘.用户将点击编辑框.然后,他们将使用扫描仪扫描,条形码将与"输入"键一起输入.需要立即清除编辑框以进行下一次扫描,并且需要处理扫描值.处理将对java bean执行各种后端操作,然后返回要在页面上显示的消息.基本上是其中之一:1.物品未找到,2.物品可用并已分配,3.物品已经分配,但您仍可以拥有它4.物品不可用
我有这个代码,整体核心代码工作正常.我通常使用onchange事件,但由于我遇到了这个问题,我转到了onkeypress事件.这也是尝试让它在IE中运行.再次,目标只针对iPad/Safari,但我也希望能够在桌面浏览器上使用它.我目前只在Chome进行测试.
在编辑框的CSJS片段中,我有以下代码:
var e = dojo.fixEvent(thisEvent);
if (e.keyCode == dojo.keys.ENTER) {
return true;
} else {
return false;
}
Run Code Online (Sandbox Code Playgroud)
我的想法是我只想在Enter上调用SSJS.
这是SSJS代码,它清除编辑框,处理值,然后设置一些viewScope变量.
// Get the value off the page and put it in to the key variable
var key:String = getComponent("scanBox").getValue();
// clear the scanbox so it's ready for the next scan.
getComponent("scanBox").setValue("");
//Managed Bean to hold the last scan value - since the scanbox is cleared we do want to show the value
Scan.setLastScan(key);
// Managed Bean to process the item.
AddToJob.processItem(key);
viewScope.put("vsShowAssignPanel", true);
viewScope.put("vsShowMessagePanel", false);
Run Code Online (Sandbox Code Playgroud)
SSJS代码设置为部分更新页面的主要内容.我正在使用bootstrap并尝试刷新页面上的所有内容,除了顶部和底部导航栏.编辑框本身位于部分刷新区域,因为我在扫描后清除了值.
最后这是问题所在:
按钮的SSJS代码正在运行TWICE.不是出于某种原因,但可能有90%的时间.我没有点击两次.我测试的方法是在桌面上使用Chrome,然后在字段中粘贴一个值,然后在键盘上输入一次.
如果我正在尝试扫描并指定带有条形码的项目.它首先运行良好.它更新对象并将字段保存到后端NotesDocument以标记它已分配.只想要我想要的.但第二次通过命中,它阻止该项目已被分配并给我错误的消息.
经过大量的反复试验后,我非常确定JSF生命周期中的某些内容会导致它运行两次.为什么我不知道.我不知道如何获得它一次.
到目前为止,我发现的唯一好的解决方法是在"AddToJob.processItem"方法中."AddToJob"是viewScope中的托管bean.在那里我存储并保留最后一个barCode.然后我做一个检查,看看价值是一样的.如果是这样,那么我认为它是在第二次运行并停止处理.
我已经在编辑控件的on change事件中使用了这个基本概念来调用代码多年.但那是在XPages Mobile Controls中,有时候事情确实有些不同.我正在尝试重新编写此应用程序以使用Bootstrap而不是XPages Mobile控件.
如果有帮助,下面是编辑控件的完整XML标记.
<xp:inputText id="scanBox" styleClass="newTarget">
<xp:this.attrs>
<xp:attr name="placeholder" value="Tap to Scan..." />
<xp:attr name="autocorrect" value="off" />
</xp:this.attrs>
<xp:this.dojoAttributes>
<xp:dojoAttribute name="autocorrect" value="off" />
</xp:this.dojoAttributes>
<xp:eventHandler event="onkeypress" submit="true" refreshMode="partial" refreshId="mainPanel">
<xp:this.script><![CDATA[var e = dojo.fixEvent(thisEvent);
if (e.keyCode == dojo.keys.ENTER) {
return true;
} else {
return false;
}]]></xp:this.script>
<xp:this.action><![CDATA[#{javascript:// Get the value off the page and put it in to the key variable
var key:String = getComponent("scanBox").getValue();
// clear the scanbox so it's ready for the next scan.
getComponent("scanBox").setValue("");
//Managed Bean to hold the last scan value - since the scanbox is cleared we do want to show the value
Scan.setLastScan(key);
// Managed Bean to process the item.
AddToJob.processItem(key);
viewScope.put("vsShowAssignPanel", true);
viewScope.put("vsShowMessagePanel", false);}]]></xp:this.action>
</xp:eventHandler></xp:inputText>
Run Code Online (Sandbox Code Playgroud)
任何信息表示赞赏.非常感谢你!!!
Enter键是一个特殊键,因为按Enter键也可以提交您当前所在的表单.在这种情况下,您实际上有两个POST请求命中服务器,一个用于部分请求,另一个用于提交表单.
您需要做的是阻止enter键使用event.preventDefaults()调用提交表单.这是更新的CSJS
var e = dojo.fixEvent(thisEvent);
if (e.keyCode == dojo.keys.ENTER) {
e.preventDefault();
return true;
} else {
return false;
}
Run Code Online (Sandbox Code Playgroud)
现在表单将不会被提交,但部分刷新将正确启动.