我有一个具有简单搜索功能的 XPage。
简单搜索由一个组合框和一个文本框输入字段组成,组合框表示包含要搜索的信息的项目名称,用户可以在其中输入要搜索的值。
“过滤器”组合框包含“RecordID”、“请求者”、“受让人”等内容。
当用户选择过滤器并输入要搜索的术语并按 Enter 键时,将在服务器上执行搜索并正确返回结果。例如,如果用户选择“RecordID”并输入“ABCD”并按 Enter 键,则返回所有在 RecordID 字段中包含“ABCD”的结果记录。如果用户选择“请求者”并输入“Joe Smith”,则返回请求者字段中包含“Joe Smith”的所有记录。这很好用。
我的问题是当我尝试向值字段添加预先输入时。预输入正在工作,但仅过滤组合框的“LAST SUBMITTED”值。示例:如果用户选择“RecordID”并且上次搜索是使用“RecordID”执行的,则 typeahead 将在用户输入信息时正确过滤 RecordID 结果。如果用户将过滤器更改为“请求者”并开始输入姓名,则不会返回结果。如果他们按 Enter 并根据请求者获取结果,然后清除值字段并开始输入另一个请求者的姓名,则预输入工作正常。
我很确定问题是由于我不知道如何在 typeahead 事件期间访问组合框的值。我的代码如下(使用 println 语句来尝试确定组合框的值。 .value 属性和 .getValue() 方法都返回组合框之前提交的值。 .getSubscribedValue() 属性是返回 null。
<xp:comboBox
id="simpleSearchFilter1"
value="#{XSPrequestSearcher.simpleSearchFilter}">
<xp:selectItems
value="#{XSPrequestSearcher.simpleSearchChoices}" />
</xp:comboBox>
<xp:inputText
id="simpleSearchValue1"
value="#{XSPrequestSearcher.simpleSearchValue}">
<xp:typeAhead
mode="partial"
valueMarkup="true"
var="searchfor"
minChars="3">
<xp:this.valueList><![CDATA[#{javascript:var obj = getComponent("simpleSearchFilter1");
var value = obj.value;
var gvalue = obj.getValue();
var svalue = obj.getSubmittedValue();
println("***********");
println("simpleSearchValue1.typeahead");
println("\t value: " + value);
println("\t gvalue: " + gvalue);
println("\t svalue: " + svalue);
XSPrequestSearcher.setSimpleSearchFilter(getComponent("simpleSearchFilter1").value);
XSPrequestSearcher.getTypeaheadChoicesSimple(searchfor); }]]></xp:this.valueList>
</xp:typeAhead>
<xp:eventHandler
event="onchange"
submit="true"
refreshMode="partial"
refreshId="#{compositeData.partialRefreshTargetID}">
<xp:this.script>
<xp:executeClientScript>
<xp:this.script><![CDATA[return !isBlank("#{id:simpleSearchValue1}");]]></xp:this.script>
</xp:executeClientScript>
</xp:this.script>
<xp:this.action><![CDATA[#{javascript:XSPrequestSearcher.setSimpleSearchFilter(getComponent("simpleSearchFilter1").value);}]]></xp:this.action>
</xp:eventHandler>
</xp:inputText>
最佳答案
当您更改组合框的值时,它不会将其值提交到服务器。由于预输入中的部分刷新在输入组件周围本地工作,因此它不知道组合框的客户端值。
所以有两个选择。首先,您可以通过在组合框中添加一个简单的事件处理程序来提交每次更改的组合框值:
<xp:eventHandler
event="onchange"
submit="true"
refreshMode="norefresh"
disableValidators="true">
</xp:eventHandler>
每当用户更改其值时,这都会进行一个简短的 AJAX 调用。在这种情况下,它不需要刷新任何内容或验证字段。
更新:
上述方法会造成 UI 滞后并使用此 snippet不按照您在评论中的建议工作。由于部分刷新操作是异步操作,因此当您启动 typeahead 时,它不会等待部分刷新操作。
但是稍微修改一下代码片段就可以了。这里的问题是,如果没有 searchFilter,searchValue 对我们来说没有任何意义。因此,我寻找一种同时提交这两种信息的方法。这可以通过与代码片段相同的方法实现。
首先,我为 typeAhead
提供了一个 id
。这很重要,尤其是当您想在同一页面上使用多个 typeAhead 时。
<xp:typeAhead
id="simpleSearch"
mode="partial"
..... other attributes ....
</xp:typeAhead>
现在我们将在 Ajax 请求中注入(inject)一些 CSJS,特别是针对 typeahead 请求。
<xp:eventHandler
event="onClientLoad"
submit="false">
<xp:this.script><![CDATA[
dojo.addOnLoad( function(){
/*** hijacking xhr request ***/
if( !dojo._xhr )
dojo._xhr = dojo.xhr;
dojo.xhr = function(){
try{
var args = arguments[1];
if( args['content'] ){
var content = args['content'];
if( content['$$ajaxmode'] ){
if( content['$$ajaxmode'] == "typeahead" ){
// Paranoid check for multiple typeahead:
if(content['$$ajaxid'] == "#{id:simpleSearch}") {
var filterType=dojo.byId("#{id:simpleSearchFilter1}").value;
content['$$value']=filterType+":"+content['$$value'];
}
}
}
}
}catch(e){}
dojo._xhr( arguments[0], arguments[1], arguments[2] );
}
});]]></xp:this.script>
</xp:eventHandler>
在这里,我们基本上检查每个预输入请求。如果某些预输入源 self 们的预输入,我们会在提交的搜索值前面添加过滤器类型。因此,我们寻找的值(value)将会改变。您需要相应地更改 typeAhead 值列表函数:
var searchFilter=@Left(searchfor, ":");
var searchValue=@Right(searchfor, ":");
// Use searchFilter and searchValue to generate a value list.
这里有一个小注释。我们正在使用 Ajax 注入(inject)。如果我们的页面使用类似的注入(inject)(例如待机对话框等),则应仔细修改诸如 dojo._xhr
之类的变量名称。
关于javascript - XPages typeahead 如何将组合框过滤器的值发送到服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25292840/