wake-up-neo.com

Bei der automatischen Vervollständigung der jQuery-Benutzeroberfläche wurden keine Ergebnisse festgestellt

Bevor Sie mich auf sie verweisen, habe ich ein halbes Dutzend Beiträge zu diesem Thema durchgesehen, aber ich weiß immer noch nicht, warum dies nicht funktioniert.

Mein Ziel ist es zu erkennen, wann die automatische Vervollständigung 0 Ergebnisse liefert. Hier ist der Code:

 $.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!'); }

  })
 }
}); 

Die Suche selbst funktioniert einwandfrei. Ich kann problemlos Ergebnisse erzielen. Nach meinem Verständnis kann ich sollte die Ergebnisse mit dem Autocomplete-Handler ("result") abfangen. In diesem Fall wird es überhaupt nicht ausgelöst. (Sogar eine allgemeine Warnung oder ein console.log, das nicht auf die Anzahl der Ergebnisse verweist, wird niemals ausgelöst.) Der geöffnete Ereignishandler zeigt die richtige Anzahl von Ergebnissen an (wenn Ergebnisse vorliegen), und die Ereignishandler zum Suchen und Schließen geben eine Ergebnisgröße an, die immer einen Schritt zurückliegt.

Ich habe das Gefühl, hier fehlt mir etwas offensichtliches und grelles, aber ich sehe es einfach nicht.

88
ScottyDont

jQueryUI 1.9

jQueryUI 1.9 hat das Widget für die automatische Vervollständigung mit dem Ereignis response gesegnet, das wir nutzen können, um festzustellen, ob keine Ergebnisse zurückgegeben wurden:

Wird nach Abschluss einer Suche ausgelöst, bevor das Menü angezeigt wird. Nützlich für die lokale Bearbeitung von Vorschlagsdaten, bei denen kein Rückruf einer benutzerdefinierten Quelloption erforderlich ist. Dieses Ereignis wird immer ausgelöst, wenn eine Suche abgeschlossen ist, auch wenn das Menü nicht angezeigt wird, weil keine Ergebnisse vorliegen oder die automatische Vervollständigung deaktiviert ist.

Aus diesem Grund wurde das Hacken in jQueryUI 1.8 durch Folgendes ersetzt:

$(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();
            }
        }
    });
});​

Beispiel: http://jsfiddle.net/andrewwhitaker/x5q6Q/


jQueryUI 1.8

Ich konnte mit der jQueryUI-API keine einfache Möglichkeit finden, dies zu tun. Sie könnten jedoch die Funktion autocomplete._response Durch Ihre eigene ersetzen und dann die Standardfunktion jQueryUI aufrufen ( aktualisiert, um die automatische Vervollständigung zu erweitern) prototype object):

var __response = $.ui.autocomplete.prototype._response;
$.ui.autocomplete.prototype._response = function(content) {
    __response.apply(this, [content]);
    this.element.trigger("autocompletesearchcomplete", [content]);
};

Binden Sie dann einen Ereignishandler an das Ereignis autocompletesearchcomplete (Inhalt ist das Ergebnis der Suche, ein Array):

$("input").bind("autocompletesearchcomplete", function(event, contents) {
    $("#results").html(contents.length);
});

Was hier vor sich geht, ist, dass Sie die Funktion response von autocomplete in einer Variablen speichern (__response) Und dann apply verwenden, um sie erneut aufzurufen. Ich kann mir keine negativen Auswirkungen dieser Methode vorstellen, da Sie die Standardmethode aufrufen. Da wir den Prototyp des Objekts ändern, funktioniert dies für alle Widgets mit automatischer Vervollständigung.

Hier ist ein funktionierendes Beispiel : http://jsfiddle.net/andrewwhitaker/VEhyV/

In meinem Beispiel wird ein lokales Array als Datenquelle verwendet, aber ich denke, das sollte keine Rolle spielen.


Update: Sie können die neue Funktionalität auch in ein eigenes Widget einbinden und so die standardmäßige Autocomplete-Funktionalität erweitern:

$.widget("ui.customautocomplete", $.extend({}, $.ui.autocomplete.prototype, {

  _response: function(contents){
      $.ui.autocomplete.prototype._response.apply(this, arguments);
      $(this.element).trigger("autocompletesearchcomplete", [contents]);
  }
}));

Ändern Ihres Anrufs von .autocomplete({...}); zu:

$("input").customautocomplete({..});

Und binden Sie dann später an das benutzerdefinierte Ereignis autocompletesearchcomplete:

$("input").bind("autocompletesearchcomplete", function(event, contents) {
    $("#results").html(contents.length);
});

Sehen Sie sich hier ein Beispiel an : http://jsfiddle.net/andrewwhitaker/VBTGJ/


Da diese Frage/Antwort einige Aufmerksamkeit auf sich gezogen hat, dachte ich, ich würde diese Antwort mit einem weiteren Weg aktualisieren, um dies zu erreichen. Diese Methode ist am nützlichsten, wenn Sie nur ein Widget für die automatische Vervollständigung auf der Seite haben. Diese Vorgehensweise kann auf ein Widget für die automatische Vervollständigung angewendet werden, das eine entfernte oder lokale Quelle verwendet:

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);
    }
});

Innerhalb von if platzieren Sie Ihre benutzerdefinierte Logik, die ausgeführt werden soll, wenn keine Ergebnisse gefunden werden.

Beispiel: http://jsfiddle.net/qz29K/

Wenn Sie eine Remote-Datenquelle verwenden, sagen Sie Folgendes:

$("#auto").autocomplete({
    source: "my_remote_src"
});

Dann müssen Sie Ihren Code so ändern, dass Sie AJAX sich selbst anrufen und erkennen können, wenn 0 Ergebnisse zurückkommen:

$("#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([]);
            }
        });
    }
});
195
Andrew Whitaker

Jeder scheint den einfachen, integrierten Weg zu ignorieren: Verwenden Sie das Ereignis 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")
    }
  }
})

Diese Funktion wurde in jQuery 1.9 als experimentelle Funktion hinzugefügt ( hier beschrieben ). Stand Juli 2017 ist es noch nicht in der API dokumentiert .

5
Mike Bethany

Wenn Sie eine entfernte Datenquelle verwenden (wie z. B. eine MySQL-Datenbank, PHP oder was auch immer auf der Serverseite), gibt es einige andere sauberere Möglichkeiten Eine Situation, in der keine Daten an den Client zurückgegeben werden müssen (ohne dass Hacks oder Änderungen am Code der Benutzeroberfläche des Kerncodes erforderlich sind).

Ich verwende PHP und MySQL als ferne Datenquelle und JSON, um Informationen zwischen ihnen zu übermitteln. In meinem Fall schien es, als ob ich jQuery-Ausnahmefehler bekomme, wenn die JSON-Anforderung keine Antwort von der Ich fand es einfacher, eine leere JSON-Antwort von der Serverseite zurückzugeben, wenn keine Daten vorhanden sind, und dann die Client-Antwort von dort zu verarbeiten:

if (preg_match("/^[a-zA-Z0-9_]*$/", $_GET['callback'])) {//sanitize callback name
    $callback = $_GET['callback'];
} else { die(); }

die($callback . "([])");

Eine andere Möglichkeit besteht darin, ein Flag in der Antwort vom Server zurückzugeben, um anzuzeigen, dass keine übereinstimmenden Daten vorhanden sind, und clientseitige Aktionen basierend auf dem Vorhandensein (und/oder Wert) des Flags in der Antwort durchzuführen. In diesem Fall würde die Antwort des Servers ungefähr so ​​aussehen:

die($callback . "([{'nodata':true}])");

Basierend auf diesem Flag können dann Aktionen clientseitig ausgeführt werden:

$.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.
    }
});
2
Zappa

Stellen Sie nach der Initialisierung Ihres Autocomplete-Elements die Option messages ein, wenn Sie die Standardbereiche für die Anzeige von Nachrichten verwenden möchten:

$(<yourselector>).autocomplete('option', 'messages', {
    noResults: 'myKewlMessage',
    results: function( amount ) {
        return amount + ( amount > 1 ? " results were" : " result was" ) + " found.";
    }
});

NOTE : Dies ist eine experimentelle API (nicht dokumentiert). Entwickler von jQuery UI untersuchen derzeit noch eine vollständige Lösung für die Manipulation und Internationalisierung von Zeichenfolgen.

2
Guntram

Ich verstehe nicht, warum der source -Parameter mit einem benutzerdefinierten Rückruf nicht genug ist:

$("#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([]);
            }
        });
    }
});
0
Salman A

Nach stundenlangem Spielen habe ich endlich einen Trick gefunden, um No match found In jQuery Autocomplete anzuzeigen. Schauen Sie sich den obigen Code an und fügen Sie einfach ein div hinzu, in meinem Fall #ulNoMatch Und dessen Stil auf displap:none. Überprüfen Sie in der Callback Success-Methode, ob das zurückgegebene Array length == 0 Enthält. Wenn es da ist, machst du deinen Tag! :)

<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>
0
Umar Malik