在你指出他们之前,是的,我已经回顾了关于这个主题的六个帖子,但我仍然因为这不起作用而受到阻碍。
我的目标是检测自动完成何时产生0结果。这是代码:
$.ajax({
url:'sample_list.foo2',
type: 'get',
success: function(data, textStatus, XMLHttpRequest) {
var suggestions=data.split(",");
$("#entitySearch").autocomplete({
source: suggestions,
minLength: 3,
select: function(e, ui) {
entityAdd(ui.item.value);
},
open: function(e, ui) {
console.log($(".ui-autocomplete li").size());
},
search: function(e,ui) {
console.log("search returned: " + $(".ui-autocomplete li").size());
},
close: function(e,ui) {
console.log("on close" + $(".ui-autocomplete li").size());
$("#entitySearch").val("");
}
});
$("#entitySearch").autocomplete("result", function(event, data) {
if (!data) { alert('nothing found!'); }
})
}
});
搜索本身运行正常,我可以得到没有问题的结果。据我了解,我应能够使用自动完成(“结果”)处理程序拦截结果。在这种情况下,它根本不会发射。 (即使是不引用结果数量的通用警报或console.log也不会触发)。 open事件处理程序显示正确的结果数(当有结果时),搜索和关闭事件处理程序报告结果总是落后一步。
我觉得我错过了一些显而易见的东西,但我只是看不到它。
答案 0 :(得分:193)
jQueryUI 1.9使用response
事件祝福自动完成小部件,我们可以利用它来检测是否没有返回任何结果:
搜索完成后,在显示菜单之前触发。对于建议数据的本地操作很有用,其中不需要自定义源选项回调。搜索完成时始终会触发此事件,即使由于没有结果或禁用自动填充功能而无法显示菜单。
因此,考虑到这一点,我们在jQueryUI 1.8中所做的黑客行为将替换为:
$(function() {
$("input").autocomplete({
source: /* */,
response: function(event, ui) {
// ui.content is the array that's about to be sent to the response callback.
if (ui.content.length === 0) {
$("#empty-message").text("No results found");
} else {
$("#empty-message").empty();
}
}
});
});
示例: http://jsfiddle.net/andrewwhitaker/x5q6Q/
我找不到使用jQueryUI API执行此操作的简单方法,但是,您可以将autocomplete._response
函数替换为您自己的函数,然后调用默认的jQueryUI函数(更新以扩展自动填充的prototype
对象):
var __response = $.ui.autocomplete.prototype._response;
$.ui.autocomplete.prototype._response = function(content) {
__response.apply(this, [content]);
this.element.trigger("autocompletesearchcomplete", [content]);
};
然后将事件处理程序绑定到autocompletesearchcomplete
事件(内容是搜索的结果,数组):
$("input").bind("autocompletesearchcomplete", function(event, contents) {
$("#results").html(contents.length);
});
这里发生的是您将自动填充的response
功能保存到变量(__response
),然后使用apply
再次调用它。因为你正在调用默认方法,所以我无法想象这种方法有任何不良影响。由于我们正在修改对象的原型,因此这适用于所有自动完成小部件。
以下是一个工作示例:http://jsfiddle.net/andrewwhitaker/VEhyV/
我的示例使用本地数组作为数据源,但我认为这不重要。
更新:您还可以将新功能包装在自己的小部件中,从而扩展默认的自动完成功能:
$.widget("ui.customautocomplete", $.extend({}, $.ui.autocomplete.prototype, {
_response: function(contents){
$.ui.autocomplete.prototype._response.apply(this, arguments);
$(this.element).trigger("autocompletesearchcomplete", [contents]);
}
}));
将来电从.autocomplete({...});
更改为:
$("input").customautocomplete({..});
然后再绑定到自定义autocompletesearchcomplete
事件:
$("input").bind("autocompletesearchcomplete", function(event, contents) {
$("#results").html(contents.length);
});
查看此处的示例:http://jsfiddle.net/andrewwhitaker/VBTGJ/
由于这个问题/答案得到了一些关注,我想我会用另一种方法来更新这个答案。当您在页面上只有一个自动完成小部件时,此方法最有用。这种方式可以应用于使用远程或本地源的自动完成小部件:
var src = [...];
$("#auto").autocomplete({
source: function (request, response) {
var results = $.ui.autocomplete.filter(src, request.term);
if (!results.length) {
$("#no-results").text("No results found!");
} else {
$("#no-results").empty();
}
response(results);
}
});
在if
内部,您可以在未检测到任何结果的情况下执行自定义逻辑。
示例: http://jsfiddle.net/qz29K/
如果您使用的是远程数据源,请说出以下内容:
$("#auto").autocomplete({
source: "my_remote_src"
});
然后你需要更改代码,以便自己进行AJAX调用,并且可以检测到0结果何时返回:
$("#auto").autocomplete({
source: function (request, response) {
$.ajax({
url: "my_remote_src",
data: request,
success: function (data) {
response(data);
if (data.length === 0) {
// Do logic for empty result.
}
},
error: function () {
response([]);
}
});
}
});
答案 1 :(得分:5)
每个人似乎都忽略了简单的内置方式:使用消息:noResults事件。
$('#field_name').autocomplete({
source: $('#field_name').data('autocomplete-source'),
messages: {
noResults: function(count) {
console.log("There were no matches.")
},
results: function(count) {
console.log("There were " + count + " matches")
}
}
})
此功能已作为实验性功能(described here)添加到jQuery 1.9中。截至2017年7月,尚未documented in the API。
答案 2 :(得分:2)
如果您正在使用远程数据源(如MySQL数据库,PHP或服务器端的任何其他内容),当没有数据返回到数据库时,还有其他一些更简洁的方法来处理这种情况。客户端(无需任何黑客或核心代码UI代码更改)。
我使用PHP和MySQL作为我的远程数据源和JSON来在它们之间传递信息。在我的情况下,如果JSON请求没有从服务器获得某种响应,我似乎得到jQuery异常错误,所以我发现当没有数据然后处理客户端时,从服务器端返回空的JSON响应更容易来自那里的回应:
if (preg_match("/^[a-zA-Z0-9_]*$/", $_GET['callback'])) {//sanitize callback name
$callback = $_GET['callback'];
} else { die(); }
die($callback . "([])");
另一种方法是在服务器的响应中返回一个标志,指示没有匹配的数据,并根据响应中标志的存在(和/或值)执行客户端操作。在这种情况下,服务器响应将类似于:
die($callback . "([{'nodata':true}])");
然后基于此标志可以在客户端执行操作:
$.getJSON('response.php?callback=?', request, function (response) {
if (typeof response[0].nodata !== 'undefined' && response[0].nodata === true) {
alert('No data to display!');
} else {
//Do whatever needs to be done in the event that there is actually data to display.
}
});
答案 3 :(得分:2)
初始化自动完成元素后,如果您想使用默认跨度进行消息指示,请设置消息选项:
$(<yourselector>).autocomplete('option', 'messages', {
noResults: 'myKewlMessage',
results: function( amount ) {
return amount + ( amount > 1 ? " results were" : " result was" ) + " found.";
}
});
注意:这是一个实验性API(未记录)。 jQuery UI开发人员仍在研究字符串操作和国际化的完整解决方案。
答案 4 :(得分:0)
玩了几个小时后,我终于找到了一个在jQuery自动完成中显示No match found
的技巧。查看上面的代码,只需在我的案例div
中添加#ulNoMatch
,并将其样式设置为displap:none
。在回调成功方法中,检查返回的数组是否具有length == 0
。如果它在那里,你去,你做了你的一天! :)
<pre><div class="ui-widget1" style="width: auto;">
<asp:TextBox ID="txtSearch" class="tb" runat="server" Width="150px">
</asp:TextBox>
<ul id="ulNoMatch" class="ui-autocomplete ui-menu ui-widget1 ui-widget1-content ui-corner-all"
role="listbox" aria-activedescendant="ui-active-menuitem" style="z-index: 16;
display: none; width: 150px;">
<li class="ui-menu-item" role="menuitem"><a class="ui-corner-all" tabindex="-1">No Matches
Found</a></li>
</ul>
</div><pre>
<b>
<b>
Enter code here
<script>
$(function () {
$("input[id$='txtSearch']").autocomplete({
source: function (request, response) {
$.ajax({
url: "splah.aspx/GetByName",
data: "{ 'strName': '" + request.term.trim() + "' }",
dataType: "json",
type: "POST",
//cacheLength: 1,
contentType: "application/json; charset=utf-8",
dataFilter: function (data) {
return data; },
success: function (data) {
var found = $.map(data.d, function (item) {
return {
value: item.Name,
id: item.id
}
});
if (found.length == 0)
{
$("#ulNoMatch").show();
}
else
{
$("#ulNoMatch").hide();
}
response(found);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
select: function (event, ui) {
$("input[id$='txtSearch']").val(ui.item.label);
$("input[id$='txtID']").val(ui.item.id);
return false;
},
minLength: 1
});
});
</script>
答案 5 :(得分:0)
我不明白为什么带有自定义回调的source
参数不足:
$("#autocomplete").autocomplete({
source: function (request, response) {
$.ajax({
url: "http://example.com/service.json",
data: {
q: this.term
},
success: function (data, textStatus, jqXHR) {
// data would be an array containing 0 or more items
console.log("[SUCCESS] search returned " + data.length + " item(s)");
response(data);
},
error: function (jqXHR, textStatus, errorThrown) {
// triggered when AJAX failed because of, for example, malformed JSON
console.log("[FAILURE] search returned error");
response([]);
}
});
}
});
答案 6 :(得分:-1)
function SearchText() {
$(".autosuggest").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Default.aspx/GetAutoCompleteData",
data: "{'username':'" + document.getElementById('txtSearch').value + "'}",
dataType: "json",
success: function (data.d) {
if ((data.d).length == 0) {
alert("no result found");
}
response(data.d);
},
error: function (result) {
alert("Error");
}
});
}
});
}
答案 7 :(得分:-1)
The easiest straight forward way to do it.
$("#search-box").autocomplete({
minLength: 2,
source:function (request, response) {
$.ajax({
url: urlPref + "/Api/SearchItems",
data: {
term: request.term
},
success: function (data) {
if (data.length == 0) {
data.push({
Id: 0,
Title: "No results found"
});
}
response(data);
}
});
},