这是我想要做的:
在 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;
}
我的想法是我只想在 Enter 上调用 SSJS。
这是清除编辑框、处理值然后设置几个 viewScope 变量的 SSJS 代码。
// 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);
SSJS 代码设置为部分更新页面的主要内容。我正在使用引导程序,并试图刷新页面上的所有内容,除了顶部和底部导航栏。编辑框本身位于部分刷新区域中,因为我在扫描后清除了值。
最后,问题来了:
按钮的 SSJS 代码正在运行两次。不是全部出于某种原因,但可能是 90% 的时间。我没有点击两次。我测试的方法是在我的桌面上使用 Chrome,我将一个值粘贴到该字段中,然后在键盘上按一次 Enter。
如果我正在尝试扫描并分配带有条形码的项目。它首先运行良好。它更新对象并将字段保存到后端 NotesDocument 以将其标记为已分配。只想要我想要的。但是第二次通过点击,它阻止了该项目已经分配并给我回了错误的信息。
经过大量试验和错误后,我相当肯定 JSF 生命周期中的某些东西导致它运行两次。为什么我不知道。我不知道如何得到它一次。
到目前为止,我发现的唯一好的解决方法是“AddToJob.processItem”方法。“AddToJob”是 viewScope 中的托管 bean。在那里我存储并保留最后一个条形码。然后我检查一下值是否相同。如果是这样,那么我假设它在第二次运行并停止处理。
多年来,我一直在编辑控件的 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>
任何信息表示赞赏。非常感谢!!!