Прежде чем вы укажете мне на них, да, я просмотрел полдюжины сообщений по этой теме, но я все еще не понимаю, почему это не работает.
Моя цель - определить, когда автозаполнение дает 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, в котором не указано количество результатов, никогда не срабатывают). Обработчик событий открытия показывает правильное количество результатов (когда есть результаты), а обработчики событий поиска и закрытия сообщают размер результата, который всегда на один шаг позади.
Мне кажется, что я упускаю здесь что-то очевидное и бросающееся в глаза, но я этого просто не вижу.
источник
Ответы:
jQueryUI 1.9
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 1.8
Мне не удалось найти простой способ сделать это с помощью 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([]); } }); } });
источник
contents[0]
Кажется, что все игнорируют простой встроенный способ: использовать событие 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") } } })
Эта функция была добавлена в jQuery 1.9 в качестве экспериментальной функции ( описывается здесь ). По состоянию на июль 2017 года это еще не задокументировано в API .
источник
Если вы используете удаленный источник данных (например, базу данных MySQL, PHP или что-то еще на стороне сервера), есть несколько других более чистых способов справиться с ситуацией, когда нет данных для возврата клиенту (без необходимости хаки или изменения кода пользовательского интерфейса основного кода).
Я использую PHP и MySQL в качестве удаленного источника данных и JSON для передачи информации между ними. В моем случае я, казалось, получал ошибки исключения jQuery, если запрос JSON не получал какого-либо ответа от сервера, поэтому мне было проще просто вернуть пустой ответ 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. } });
источник
После инициализации элемента автозаполнения установите параметр сообщений, если вы хотите использовать диапазоны по умолчанию для индикации сообщений:
$(<yourselector>).autocomplete('option', 'messages', { noResults: 'myKewlMessage', results: function( amount ) { return amount + ( amount > 1 ? " results were" : " result was" ) + " found."; } });
ПРИМЕЧАНИЕ . Это экспериментальный API (не документированный). Разработчики пользовательского интерфейса jQuery все еще исследуют полное решение для обработки строк и интернационализации.
источник
После нескольких часов игры я наконец нашел трюк для отображения
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>
источник
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); } }); },
источник
Я не понимаю , почему
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([]); } }); } });
источник
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"); } }); } }); }
источник