在 jQuery UI 自动完成上没有检测到结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4718968/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detecting no results on jQuery UI autocomplete
提问by ScottyDont
Before you point me to them, yes, I have reviewed the half dozen posts on this topic, but I am still stymied as to why this doesn't work.
在你向我指出他们之前,是的,我已经查看了关于这个主题的六篇文章,但我仍然不明白为什么这不起作用。
My goal is to detect when the autocomplete yields 0 results. Here's the code:
我的目标是检测自动完成何时产生 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!'); }
})
}
});
The search itself works fine, I can get results to appear without a problem. As I understand it, I shouldbe able to intercept the results with the autocomplete("result") handler. In this case, it never fires at all. (Even a generic alert or console.log that doesn't reference the number of results never fires). The open event handler shows the correct number of results (when there are results), and the search and close event handlers report a result size that is always one step behind.
搜索本身运行良好,我可以毫无问题地显示结果。据我了解,我应该能够使用 autocomplete("result") 处理程序拦截结果。在这种情况下,它根本不会触发。(即使是不引用结果数量的通用警报或 console.log 也永远不会触发)。open 事件处理程序显示正确的结果数(当有结果时),而 search 和 close 事件处理程序报告的结果大小总是落后一步。
I feel like I'm missing something obvious and glaring here but I just don't see it.
我觉得我在这里遗漏了一些明显而明显的东西,但我只是没有看到它。
回答by Andrew Whitaker
jQueryUI 1.9
jQueryUI 1.9
jQueryUI 1.9 has blessed the autocomplete widget with the response
event, which we can leverage to detect if no results were returned:
jQueryUI 1.9 为自动完成小部件提供了response
事件,我们可以利用它来检测是否没有返回结果:
Triggered after a search completes, before the menu is shown. Useful for local manipulation of suggestion data, where a custom source option callback is not required. This event is always triggered when a search completes, even if the menu will not be shown because there are no results or the Autocomplete is disabled.
在搜索完成后,在菜单显示之前触发。对于不需要自定义源选项回调的建议数据的本地操作很有用。此事件总是在搜索完成时触发,即使由于没有结果或禁用自动完成而不会显示菜单。
So, with that in mind, the hacking we had to do in jQueryUI 1.8 is replaced with:
因此,考虑到这一点,我们必须在 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();
}
}
});
});?
Example:http://jsfiddle.net/andrewwhitaker/x5q6Q/
示例:http : //jsfiddle.net/andrewwhitaker/x5q6Q/
jQueryUI 1.8
jQueryUI 1.8
I couldn't find a straightforward way to do this with the jQueryUI API, however, you could replace the autocomplete._response
function with your own, and then call the default jQueryUI function (updated to extend the autocomplete's prototype
object):
我找不到使用 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]);
};
And then bind an event handler to the autocompletesearchcomplete
event (contents is the result of the search, an array):
然后给事件绑定一个事件处理器autocompletesearchcomplete
(contents是搜索的结果,一个数组):
$("input").bind("autocompletesearchcomplete", function(event, contents) {
$("#results").html(contents.length);
});
What's going on here is that you're saving autocomplete's response
function to a variable (__response
) and then using apply
to call it again. I can't imagine any ill-effects from this method since you're calling the default method. Since we're modifying the object's prototype, this will work for all autocomplete widgets.
这里发生的事情是您将自动完成response
功能保存到一个变量 ( __response
) 中,然后使用apply
它再次调用它。由于您正在调用默认方法,因此我无法想象此方法有任何不良影响。由于我们正在修改对象的原型,这将适用于所有自动完成小部件。
Here's a working example: http://jsfiddle.net/andrewwhitaker/VEhyV/
这是一个工作示例:http: //jsfiddle.net/andrewwhitaker/VEhyV/
My example uses a local array as a data source, but I don't think that should matter.
我的示例使用本地数组作为数据源,但我认为这无关紧要。
Update:You could also wrap the new functionality in its own widget, extending the default autocomplete functionality:
更新:您还可以将新功能包装在自己的小部件中,扩展默认的自动完成功能:
$.widget("ui.customautocomplete", $.extend({}, $.ui.autocomplete.prototype, {
_response: function(contents){
$.ui.autocomplete.prototype._response.apply(this, arguments);
$(this.element).trigger("autocompletesearchcomplete", [contents]);
}
}));
Changing your call from .autocomplete({...});
to:
将您的呼叫从更改.autocomplete({...});
为:
$("input").customautocomplete({..});
And then bind to the custom autocompletesearchcomplete
event later:
然后autocompletesearchcomplete
稍后绑定到自定义事件:
$("input").bind("autocompletesearchcomplete", function(event, contents) {
$("#results").html(contents.length);
});
See an example here: http://jsfiddle.net/andrewwhitaker/VBTGJ/
在此处查看示例:http: //jsfiddle.net/andrewwhitaker/VBTGJ/
Since this question/answer has gotten some attention, I thought I'd update this answer with yet another way to accomplish this. This method is most useful when you have only oneautocomplete widget on the page. This way of doing it can be applied to an autocomplete widget that uses a remote or local source:
由于这个问题/答案引起了一些关注,我想我会用另一种方式来更新这个答案来实现这一点。当页面上只有一个自动完成小部件时,此方法最有用。这种方式可以应用于使用远程或本地源的自动完成小部件:
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);
}
});
Inside the if
is where you would place your custom logic to execute when no results are detected.
里面的if
是您将放置您的定制逻辑没有检测结果时执行。
Example:http://jsfiddle.net/qz29K/
示例:http : //jsfiddle.net/qz29K/
If you are using a remote data source, say something like this:
如果您使用的是远程数据源,请这样说:
$("#auto").autocomplete({
source: "my_remote_src"
});
Then you'll need to change your code so that you make the AJAX call yourself and can detect when 0 results come back:
然后您需要更改您的代码,以便您自己进行 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([]);
}
});
}
});
回答by Mike Bethany
Everyone seems to be ignoring the easy, built-in way: use the messages:noResults event.
每个人似乎都忽略了简单的内置方式:使用 messages: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")
}
}
})
This feature was added in jQuery 1.9, as an experimental feature (described here). As at July 2017, it is not yet documented in the API.
这个特性是在 jQuery 1.9 中添加的,作为一个实验特性(描述在这里)。截至 2017 年 7 月,它尚未记录在 API 中。
回答by Guntram
After initializing your autocomplete element, set the messages option if you wanna use the default spans for message indication:
初始化自动完成元素后,如果要使用默认跨度进行消息指示,请设置消息选项:
$(<yourselector>).autocomplete('option', 'messages', {
noResults: 'myKewlMessage',
results: function( amount ) {
return amount + ( amount > 1 ? " results were" : " result was" ) + " found.";
}
});
NOTE: This is an experimental API (not documented). jQuery UI developers are still investigating a full solution for string manipulation and internationalization.
注意:这是一个实验性的 API(未记录)。jQuery UI 开发人员仍在研究字符串操作和国际化的完整解决方案。
回答by Zappa
If you are using a remote data source (like a MySQL database, PHP, or whatever on the server side) there are a couple of other cleaner ways to handle a situation when there's no data to return to the client (without the need for any hacks or core code UI code changes).
如果您使用的是远程数据源(如 MySQL 数据库、PHP或服务器端的任何数据源),还有其他几种更简洁的方法可以处理没有数据返回给客户端的情况(无需任何数据) hacks 或核心代码 UI 代码更改)。
I use PHP and MySQL as my remote data source and JSON to pass information between them. In my case I seemed to get jQuery exception errors if the JSON request did not get some sort of response from the server, so I found it easier to just return an empty JSON response from the server side when there's no data and then handle the client response from there:
我使用 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 . "([])");
Another way would be to return a flag in the response from the server to indicate that there's no matching data and perform actions client side based on the presence (and or value) of the flag in the response. In this case the servers response would be something like:
另一种方法是在来自服务器的响应中返回一个标志,以指示没有匹配的数据,并根据响应中标志的存在(和/或值)在客户端执行操作。在这种情况下,服务器响应将类似于:
die($callback . "([{'nodata':true}])");
Then based on this flag actions can be performed client side:
然后可以基于此标志执行客户端操作:
$.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.
}
});
回答by Umar Malik
After hours playing I finally found a trick to display No match found
in jQuery autocomplete. Look at the above code and simply add a div
, in my case #ulNoMatch
and its style set to displap:none
. In the callback success method check if the array returned has length == 0
. If it is there you go, you made your day! :)
玩了几个小时后,我终于找到了No match found
在 jQuery 自动完成中显示的技巧。查看上面的代码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>
回答by Salman A
I don't see why source
parameter with a custom callback is notenough:
我不明白为什么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([]);
}
});
}
});
回答by Bishoy Hanna
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);
}
});
},
回答by selvin john
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");
}
});
}
});
}