Обнаруживая никаких результатов по пользовательского интерфейса jQuery автозаполнения
прежде чем вы укажете мне на них, да, я просмотрел полдюжины сообщений на эту тему, но я все еще в тупике, почему это не работает.
моя цель-определить, когда автозаполнение дает 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!'); }
})
}
});
сам поиск работает нормально, я могу получить результаты, чтобы появиться без проблем. Как я понимаю, я должны иметь возможность перехватывать результаты с помощью обработчика автозаполнения("результат"). В этом случае он никогда не срабатывает совсем. (Даже общее предупреждение или консоль.журнал, который не ссылается на количество результатов, никогда не срабатывает). Обработчик событий open показывает правильное количество результатов (если есть результаты), а обработчики событий search и close сообщают о размере результата, который всегда находится на один шаг позади.
Я чувствую, что я упускаю что-то очевидное и вопиющее здесь, но я просто не вижу этого.
8 ответов:
jQueryUI 1.9
jQueryUI 1.9 благословил виджет autocomplete с
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
я не мог найти простой способ сделать это с помощью API jQueryUI, однако вы можете заменить
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({...});to:$("input").customautocomplete({..});а затем привязать к пользовательскому событие:
$("input").bind("autocompletesearchcomplete", function(event, contents) { $("#results").html(contents.length); });Смотрите пример здесь: http://jsfiddle.net/andrewwhitaker/VBTGJ/
поскольку этот вопрос / ответ получил некоторое внимание, я подумал, что обновлю этот ответ еще одним способом для этого. Этот метод особенно полезен, когда у вас есть только один виджет autocomplete на странице. Этот способ можно применить к виджету автозаполнения, который использует удаленный или локальный источник:
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([]); } }); } });
Если вы используете удаленный источник данных (например, базу данных MySQL, PHP, или что-то на стороне сервера) есть несколько других более чистых способов справиться с ситуацией, когда нет данных для возврата клиенту (без необходимости каких-либо хаков или изменений кода основного кода UI).
Я использую 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. } });
Кажется, что все игнорируют простой, встроенный способ: используйте событие 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.
после инициализации элемента автозаполнения установите параметр сообщения, если вы хотите использовать промежутки по умолчанию для индикации сообщения:
$(<yourselector>).autocomplete('option', 'messages', { noResults: 'myKewlMessage', results: function( amount ) { return amount + ( amount > 1 ? " results were" : " result was" ) + " found."; } });Примечание: Это экспериментальный API (не документально). разработчики jQuery UI все еще исследуют полное решение для обработки строк и интернационализации.
после нескольких часов игры я, наконец, нашел трюк для отображения
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>
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"); } }); } }); }
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); } }); },
Comments