Typeahead的奇怪行为 - 搜索字符串与结果一起返回

时间:2013-09-13 06:27:00

标签: xpages

长度道歉。我正在玩一个花哨的先行者,我遇到了一个我无法解释的问题。我找到了修复,但修复没有意义,所以我想知道是否有人可以查看我的示例并解释发生了什么,如果它是某种类型的错误?我已经删除了大部分功能,以提供一个简单的示例来演示。

场景:我有一个文本框,花式预测。除此之外,我有一个按钮可以将新找到的值附加到第二个字段中。我使用第二个字段来驱动重复控件,显示迄今为止选择的所有值。代码

结果:要对此进行测试,请在字段中输入“ab”,然后选择任意选项,然后点击“添加”链接。重复显示(,abcd)正如您所期望的那样。测试2,重复该过程两次。重复将显示(,abcd,ab,abcd)。出于某种原因,'ab'被添加到第二个字段中。第三次测试 - 输入ab,选择一个选项,添加。输入'bc',选择一个选项,添加。键入cd,但不是选择选项,而是单击“保存”按钮。然后重复显示(,abcd,bc,abce,cd)。我根本无法解释。

解决方法:为了使其正常工作,我可以将链接的刷新类型从部分更改为完整。我不知道为什么这会使它工作,但确实如此。我不知道我是否真的想这样做,但如果必须,我会的。这是一个相当复杂的形式,除非必须,否则我宁愿不做全面刷新。

代码:这是一个显示问题的缩减xpage:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
    <xp:this.data>
        <xp:dominoDocument var="document1" formName="Test">
        </xp:dominoDocument>
    </xp:this.data>
    <xp:panel id="mainPanel">
        <xp:button value="Save" id="button1">
            <xp:eventHandler event="onclick" submit="true"
                refreshMode="complete">
                <xp:this.action>
                    <xp:saveDocument var="document1"></xp:saveDocument>
                </xp:this.action>
            </xp:eventHandler>
        </xp:button>
        <xp:inputText id="objName1" value="#{document1.objName}">
            <xp:typeAhead mode="full" minChars="2" valueMarkup="true"
                var="searchValue" id="typeAhead1">
                <xp:this.valueList><![CDATA[#{javascript:   //In here I usually do some searching to find a result set, but for the purposes of a test, let's just do an array
    var mapResults:java.util.TreeMap = new java.util.TreeMap();
    mapResults.put("abcd", "abcd");
    mapResults.put("abce", "abce");
    mapResults.put("abcf", "abcf");
    mapResults.put("abcg", "abcg");
    mapResults.put("abch", "abch");
    mapResults.put("abci", "abci");
    //Now format the results
    var returnList = "<ul>";
    //All results are in the TreeMap and are sorted.  Now add them to the output
    var iter:Iterator = mapResults.entrySet().iterator();
    while (iter.hasNext()) {
        var nextEntry = iter.next();
        returnList += "<li>" + nextEntry.getValue() +"</li>";
    }
    //Lastly, close off the UL tag and return
    returnList += "</ul>";
    return returnList;}]]></xp:this.valueList>
            </xp:typeAhead>
        </xp:inputText>
        <xp:link escape="true" text="Add Another Object" id="link1">
            <xp:eventHandler event="onclick" submit="true"
                refreshMode="partial" id="eventHandler1" refreshId="mainPanel">
                <xp:this.action><![CDATA[#{javascript:var currentVals = document1.getItemValueArray("addObjName");
//check for null value in first item in array - happens
//if we clear the array from the 'cross' buttons in the repeat
if (currentVals[0] == null) {
    currentVals = new Array("");
}
//get the value from the object name field and whack it on the end
var newValue = getComponent("objName1").getValue();
//Put the value into a test field so we can prove that the value wasn't added below
document1.replaceItemValue("test1", newValue);
//Now add it to the field - where is the search text coming from?
currentVals.push(newValue);
document1.replaceItemValue("addObjName", currentVals);
getComponent("objName1").setValue("");
}]]></xp:this.action>
            </xp:eventHandler>
        </xp:link>
        <xp:repeat id="repeat1" rows="30" var="rowData" indexVar="index"
            repeatControls="false">
            <xp:this.value><![CDATA[#{javascript:document1.getItemValueArray("addObjName")}]]></xp:this.value>
            <xp:panel tagName="div">
                <xp:link escape="true" id="link2" title="Remove from list">
                    <xp:image url="/vwicn081.gif" id="image1">
                        <xp:eventHandler event="onclick" submit="true"
                            refreshMode="partial" refreshId="mainPanel" id="eventHandler2">
                            <xp:this.action><![CDATA[#{javascript://remove an entry (string) from a list of strings (thanks to Mark Leusink)
Array.prototype.removeEntry = function( entry:String ) {
  if ( @IsNotMember(entry, this)) {
    return this;
  }
  var res = @Trim( @Replace(this, entry, "") );
  return (typeof res == "string" ? (res.length==0 ? [] : [res]) : res);
}
var oldArray:Array = document1.getItemValueArray("addObjName");
var myArray = oldArray.removeEntry(oldArray[index]);
document1.replaceItemValue("addObjName", myArray);
}]]></xp:this.action>
                        </xp:eventHandler>
                    </xp:image>
                </xp:link>
                <xp:text escape="true" id="computedField1" value="#{javascript:rowData}">
                </xp:text>
            </xp:panel>
        </xp:repeat>
        <xp:text escape="true" id="computedField2">
            <xp:this.value><![CDATA[#{javascript:"and here is what was added in the link:"}]]></xp:this.value>
        </xp:text>
        <xp:text escape="true" id="computedField3" value="#{document1.test1}">
        </xp:text>
    </xp:panel>
</xp:view>

任何接受者?对此有合理的解释,还是我应该使用我的解决方法并停止做一个学究?

更新 使用上面的XPage,我还可以复制以下场景:

步骤1:在字段中输入“abc”,从选项中选择“abcd”,然后单击“添加”链接。一切都好。

步骤2:输入'ab'然后等待,然后输入'c',然后选择'abce'。再添一次。这增加了ab,abc,abce。

步骤3:键入ab然后等待,然后键入c,然后不要选择一个选项,而是选择保存。这会添加ab,abc - 即使没有单击链接将值添加到第二个字段。

步骤4:输入ab,等待,输入c,选择“abcf”并单击“添加”。这次只添加了abcf。

我正在努力将此与Sven的回答相提并论。部分更新有效,所以我知道他是对的。在上面的步骤2中,我认为先行代码正在执行两次,每次触发链接的onClick事件,最后链接的onClick事件正在运行。步骤3中的类似事情 - 在该示例中根本没有单击链接,但onClick代码仍在运行。在步骤4中,在保存之后,typeahead正在执行两次,但这次它没有执行onClick代码。

现在我觉得我明白了,即使我不喜欢它。正如Sven所说,$$ xspsubmitid标识了将数据提交给服务器的元素 - 在最后一次提交操作中。所以在这种情况下,它会记住之前的提交状态并重复这一点 - 所以当你在普通保存后立即执行它时,你不会得到任何额外的代码,但是当你在链接中的事件之后这样做时,它会提交该页面的方式与链接相同 - 完成onClick代码。

这可能是为什么这样做是件好事,但我的头疼,问题解决了!谢谢Sven!

1 个答案:

答案 0 :(得分:2)

更新字段/数组的值是你的预先输入。在输入框中键入第二个或更多字符时,输入框中的当前数据将发送到服务器,并更新文档中的值。点击链接时,会再次添加该值。

修改 您可以通过将输入模式更改为“部分”

来解决此问题

编辑2: 类型化的刷新模式之间的区别在于如何将数据发送到服务器:在完全刷新的情况下,数据通过 POST 请求发送,在部分刷新的情况下,数据作为 GET 请求发送。

让我们看一下不同的HTTP请求:

1。)部分模式

Partial mode / HTTP GET

2.。完整模式

Full mode / HTTP POST

正如您在两个营养素中所看到的,在完整模式下,有更多“字段”发送到服务器。最有趣的是 $$ xspsubmitid :目前它是空的。但是,一旦我们点击链接,该字段就会填充链接的ID:

Link clicked

$$ xspsubmitid 标识将数据提交到服务器的元素。在这种情况下,链接和服务器处理链接的代码。

现在问题是在完整模式下输出类型: enter image description here

如您所见, $$ xspsubmitid 始终添加到POST请求中,这就是服务器为每个预先请求执行链接的click事件的原因。