2013-10-30 77 views
2

这就是我想做的事:的XPages事件代码执行两次而不是一次

在一个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; 
} 

的想法是,我只是想打电话给SSJS上的Enter键。

下面是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); 

SSJS代码被设置为部分更新页面的主要内容。我使用引导程序,并试图刷新页面上除顶部和底部导航栏外的所有内容。由于我在扫描后清除了值,编辑框本身在部分刷新区域中。

最后,这里的问题:

按钮的SSJS代码被运行两次。不是所有的原因,但可能90%的时间。我不会点击两次。我测试的方式是在我的桌面上使用Chrome,然后将值粘贴到该字段中,然后在键盘上按一次Enter。

如果我正在尝试扫描并指定带有条形码的项目。它首先运行良好。它会更新对象并将一个字段保存到后端NotesDocument中以将其标记为已分配。只是想要我想要的。但是第二次通过命中,它阻止了该项目已被分配,并给我回错信息。

经过大量的试验和错误之后,我相当确定JSF生命周期中的某些内容导致它运行两次。为什么我不知道。我不知道如何获得一次。

到目前为止我发现的唯一好的解决方法是在“AddToJob.processItem”方法中。 “AddToJob”是viewScope中的一个托管bean。在那里我存储并保留最后一个条码。然后我做一个检查,看看价值是一样的。如果是这样,那么我认为它在第二次运行并停止处理。

我已经在编辑控件的变化事件中使用了调用代码多年的基本概念。但那是在XPages Mobile Controls内部,有时候事情在那里的表现会有所不同。我试图重新编写这个应用程序来使用Bootstrap而不是XPages移动控件。

下面是编辑控件的完整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> 

任何信息表示赞赏。非常感谢你!!!

回答

7

回车键是一个特殊的一个,因为按enter也可以提交您目前的形式。在这种情况下,你实际上有两个POST请求击中服务器,一个用于部分请求,然后又当表单提交。

你需要做的是防止输入键使用的event.preventDefaults()调用提交表单什么。这里是更新的CSJS

var e = dojo.fixEvent(thisEvent); 
if (e.keyCode == dojo.keys.ENTER) { 
    e.preventDefault(); 
    return true; 
} else { 
    return false; 
} 

现在表单将不会被提交,但部分刷新将正确触发。

+0

另一个非常简单的方法是在style:“display:none”的某处放置一个输入字段:-) –

0

请原谅我,如果我在这里失去了一些东西,但在我看来,你已经设定了一个不必要的复杂设计。

为什么CSJS或SSJS甚至需要?

含义,你有没有尝试过一些简单的标记和豆做处理?

示例标记:

<xp:panel 
id="panelbarcode"> 
<xp:inputText 
    id="barcode1" 
    value="#{MyBean.barcode}"> 
    <xp:eventHandler 
     event="onchange" 
     submit="true" 
     refreshMode="partial" 
     refreshId="panelbarcode" /> 
</xp:inputText> 
</xp:panel> 

例bean代码:

public class MyBean implements Serializable { 

private static final long serialVersionUID = 8541L; 

// Zero-Argument Constructor 
public MyBean() {} 

public String getBarcode() { 
    // give out a barcode here, 
    // or return "" for an empty barcode 
    return ""; 
} 

public void setBarCode(String barcode) { 
    // process the scanned in barcode 
} 
} 

(编辑摆脱愚蠢 “的onClick” 事件)

0

大卫,

不是一个真正的特定的XPage解决方案,但是我必须在Notes客户端(扫描条形码的位置)执行此操作处理,然后该字段被清除,然后可以扫描下一个。操作员不在客户端(其蓝牙扫描仪)。

我的解决办法,我承认是有点讨厌的是使用一个NotesTimer - 从而使字段内容进行了检查,看它是否是空的,或者如果它有相同的值之前。为了确保我没有捕捉到部分扫描,我进行了两次检查,如果值没有改变,我就处理它。

所以在这一切之后 - 无法您使用JavaScript计时器,并按照同样的逻辑?

相关问题