Zanim mi do nich wskażesz, tak, przejrzałem pół tuzina postów na ten temat, ale nadal nie wiem, dlaczego to nie działa.
Moim celem jest wykrycie, kiedy autouzupełnianie daje 0 wyników. Oto kod:
$.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!'); }
})
}
});
Samo wyszukiwanie działa dobrze, wyniki pojawiają się bez problemu. Jak rozumiem, powinienem być w stanie przechwycić wyniki za pomocą modułu obsługi autouzupełniania („wyników”). W tym przypadku w ogóle nie strzela. (Nawet ogólny alert lub console.log, który nie odwołuje się do liczby wyników, nigdy nie jest uruchamiany). Procedura obsługi zdarzenia otwierania pokazuje poprawną liczbę wyników (jeśli istnieją wyniki), a programy obsługi zdarzeń wyszukiwania i zamykania raportują rozmiar wyniku, który jest zawsze o jeden krok za.
Czuję, że brakuje mi czegoś oczywistego i rażącego, ale po prostu tego nie widzę.
źródło
Odpowiedzi:
jQueryUI 1.9.0
jQueryUI 1.9 pobłogosławił widżet autouzupełniania
response
zdarzeniem, które możemy wykorzystać do wykrycia, jeśli żadne wyniki nie zostały zwrócone:Mając to na uwadze, hakowanie, które musieliśmy zrobić w jQueryUI 1.8, zostało zastąpione przez:
$(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(); } } }); });
Przykład: http://jsfiddle.net/andrewwhitaker/x5q6Q/
jQueryUI 1.8.0
Nie mogłem znaleźć prostego sposobu na zrobienie tego za pomocą interfejsu API jQueryUI, jednak możesz zastąpić
autocomplete._response
funkcję własną, a następnie wywołać domyślną funkcję jQueryUI ( zaktualizowaną w celu rozszerzeniaprototype
obiektu autouzupełniania ) :var __response = $.ui.autocomplete.prototype._response; $.ui.autocomplete.prototype._response = function(content) { __response.apply(this, [content]); this.element.trigger("autocompletesearchcomplete", [content]); };
Następnie powiąż procedurę obsługi zdarzeń ze
autocompletesearchcomplete
zdarzeniem (zawartość jest wynikiem wyszukiwania, tablicą):$("input").bind("autocompletesearchcomplete", function(event, contents) { $("#results").html(contents.length); });
Chodzi tutaj o to, że zapisujesz
response
funkcję autouzupełniania w zmiennej (__response
), a następnie używasz jejapply
do ponownego wywołania. Nie mogę sobie wyobrazić żadnych złych skutków tej metody, ponieważ wywołujesz metodę domyślną. Ponieważ modyfikujemy prototyp obiektu, będzie to działać dla wszystkich widżetów autouzupełniania.Oto działający przykład : http://jsfiddle.net/andrewwhitaker/VEhyV/
Mój przykład używa tablicy lokalnej jako źródła danych, ale nie sądzę, żeby to miało znaczenie.
Aktualizacja: Możesz również opakować nową funkcjonalność we własnym widżecie, rozszerzając domyślną funkcję autouzupełniania:
$.widget("ui.customautocomplete", $.extend({}, $.ui.autocomplete.prototype, { _response: function(contents){ $.ui.autocomplete.prototype._response.apply(this, arguments); $(this.element).trigger("autocompletesearchcomplete", [contents]); } }));
Zmiana połączenia z
.autocomplete({...});
na:$("input").customautocomplete({..});
A później powiąż ze
autocompletesearchcomplete
zdarzeniem niestandardowym :$("input").bind("autocompletesearchcomplete", function(event, contents) { $("#results").html(contents.length); });
Zobacz przykład tutaj : http://jsfiddle.net/andrewwhitaker/VBTGJ/
Ponieważ to pytanie / odpowiedź zwróciło uwagę, pomyślałem, że zaktualizuję tę odpowiedź o jeszcze inny sposób, aby to osiągnąć. Ta metoda jest najbardziej przydatna, gdy na stronie znajduje się tylko jeden widżet autouzupełniania. Ten sposób można to zrobić w przypadku widgetu autouzupełniania, który korzysta ze źródła zdalnego lub lokalnego:
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); } });
Wewnątrz
if
jest miejsce, w którym można umieścić niestandardową logikę do wykonania, gdy nie zostaną wykryte żadne wyniki.Przykład: http://jsfiddle.net/qz29K/
Jeśli korzystasz ze zdalnego źródła danych, powiedz coś takiego:
$("#auto").autocomplete({ source: "my_remote_src" });
Następnie musisz zmienić kod, aby samodzielnie wykonać połączenie AJAX i wykryć, kiedy wróci 0 wyników:
$("#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([]); } }); } });
źródło
contents[0]
Wydaje się, że wszyscy ignorują prosty, wbudowany sposób: użyj zdarzenia 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") } } })
Ta funkcja została dodana w jQuery 1.9 jako funkcja eksperymentalna ( opisana tutaj ). W lipcu 2017 nie jest to jeszcze udokumentowane w API .
źródło
Jeśli korzystasz ze zdalnego źródła danych (takiego jak baza danych MySQL, PHP lub cokolwiek po stronie serwera), istnieje kilka innych czystszych sposobów radzenia sobie z sytuacją, gdy nie ma danych do zwrócenia do klienta (bez potrzeby hacki lub podstawowe zmiany kodu interfejsu użytkownika).
Używam PHP i MySQL jako mojego zdalnego źródła danych i JSON do przekazywania informacji między nimi. W moim przypadku wydawało mi się, że otrzymuję błędy wyjątku jQuery, jeśli żądanie JSON nie otrzymało jakiejś odpowiedzi z serwera, więc łatwiej mi było po prostu zwrócić pustą odpowiedź JSON po stronie serwera, gdy nie ma danych, a następnie obsłużyć klienta odpowiedź stamtąd:
if (preg_match("/^[a-zA-Z0-9_]*$/", $_GET['callback'])) {//sanitize callback name $callback = $_GET['callback']; } else { die(); } die($callback . "([])");
Innym sposobem byłoby zwrócenie flagi w odpowiedzi z serwera, aby wskazać, że nie ma pasujących danych i wykonać działania po stronie klienta na podstawie obecności (i lub wartości) flagi w odpowiedzi. W tym przypadku odpowiedź serwera wyglądałaby następująco:
die($callback . "([{'nodata':true}])");
Następnie na podstawie tej flagi można wykonać akcje po stronie klienta:
$.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. } });
źródło
Po zainicjowaniu elementu autouzupełniania ustaw opcję wiadomości, jeśli chcesz używać domyślnych zakresów do wskazywania wiadomości:
$(<yourselector>).autocomplete('option', 'messages', { noResults: 'myKewlMessage', results: function( amount ) { return amount + ( amount > 1 ? " results were" : " result was" ) + " found."; } });
UWAGA : to jest eksperymentalny interfejs API (nieudokumentowany). Programiści jQuery UI wciąż badają pełne rozwiązanie do manipulacji ciągami znaków i internacjonalizacji.
źródło
Po godzinach grania w końcu znalazłem sztuczkę do wyświetlenia
No match found
w autouzupełnianiu jQuery. Spójrz na powyższy kod i po prostu dodajdiv
, w moim przypadku#ulNoMatch
i jego styl ustawiony nadisplap:none
. W metodzie powodzenia wywołania zwrotnego sprawdź, czy zwrócona tablica malength == 0
. Jeśli tam jesteś, masz dobry dzień! :)<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>
źródło
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); } }); },
źródło
Nie rozumiem, dlaczego
source
parametr z niestandardowym wywołaniem zwrotnym nie wystarczy:$("#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([]); } }); } });
źródło
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"); } }); } }); }
źródło