88 votes

Détecter aucun résultat sur l'auto-complétion de l'interface utilisateur jQuery

Avant de me pointer à eux, oui, j'ai examiné la demi-douzaine de posts sur ce sujet, mais je suis toujours bloqué pour expliquer pourquoi cela ne fonctionne pas.

Mon objectif est de détecter lors de la saisie semi-automatique des rendements 0 résultats. Voici le 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!'); }

  })
 }
}); 

La recherche en elle-même fonctionne très bien, je peux obtenir des résultats pour un affichage sans problème. Si je comprends bien, je devrais être en mesure d'intercepter les résultats avec la saisie semi-automatique("résultat") gestionnaire. Dans ce cas, il n'est jamais déclenché. (Même le générique d'alerte ou de la console.journal qui ne fait pas référence au nombre de résultats n'est jamais déclenché). Le gestionnaire d'événements ouvrir affiche le nombre de résultats (quand il y a des résultats), et de la recherche et de fermer les gestionnaires d'événements rapport à un résultat qui est toujours un temps de retard.

J'ai l'impression de rater quelque chose d'évident et flagrant ici, mais je ne vois pas.

196voto

Andrew Whitaker Points 58588

jQueryUI 1.9

jQueryUI 1.9 a béni le widget de saisie semi-automatique avec l' response événement, dont nous pouvons tirer profit pour détecter si aucun résultat n'a été retourné:

Déclenché après une recherche terminée, avant que le menu est affiché. Utile pour les locaux de manipulation de la suggestion, de données, d'où une coutume source de l'option de rappel n'est pas nécessaire. Cet événement est toujours déclenché une fois la recherche terminée, même si le menu n'apparaît pas, car il n'y a pas des résultats ou de la saisie semi-automatique est désactivé.

Donc, avec cela à l'esprit, le piratage, nous avons eu à faire à jQueryUI 1.8 est remplacé par:

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

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


jQueryUI 1.8

Je ne pouvais pas trouver un moyen simple de faire cela avec la jQueryUI API, cependant, vous pouvez remplacer l' autocomplete._response fonction de vos propres, et ensuite appeler le défaut de jQueryUI fonction (mis à jour afin de prolonger la saisie semi-automatique de l' prototype objet):

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

Et puis de lier un gestionnaire d'événement à l' autocompletesearchcomplete événement (le contenu est le résultat de la recherche, un tableau):

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

Ce qui se passe ici, c'est que vous êtes en train d'enregistrer la saisie semi-automatique de l' response fonction à une variable (__response) et ensuite à l'aide d' apply de l'appeler à nouveau. Je ne peux pas imaginer tous les mauvais effets de cette méthode puisque vous êtes à l'appel de la méthode par défaut. Puisque nous sommes modifier le prototype de l'objet, cela fonctionne pour tous de saisie semi-automatique des widgets.

Voici un exemple: http://jsfiddle.net/andrewwhitaker/VEhyV/

Mon exemple utilise un local tableau en tant que source de données, mais je ne pense pas que devrait avoir de l'importance.


Mise à jour: Vous pouvez aussi envelopper la nouvelle fonctionnalité dans son propre widget, l'extension de la valeur par défaut de la fonctionnalité de saisie semi-automatique:

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

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

Changer votre appel à partir d' .autocomplete({...}); :

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

Et puis lier à la coutume autocompletesearchcomplete plus tard:

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

Voir un exemple ici: http://jsfiddle.net/andrewwhitaker/VBTGJ/


Depuis que cette question/réponse a obtenu une certaine attention, je pensais que je mettrais à jour cette réponse avec encore une autre façon d'accomplir cette tâche. Cette méthode est particulièrement utile lorsque vous n'avez qu' une saisie semi-automatique widget sur la page. Cette manière de faire peut être appliqué à un widget de saisie semi-automatique qui utilise un local ou à distance 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);
    }
});

À l'intérieur de l' if est l'endroit où vous placez votre logique personnalisée pour s'exécuter lors de l'absence de résultats sont détectés.

Exemple: http://jsfiddle.net/qz29K/

Si vous utilisez une source de données distante, dire quelque chose comme ceci:

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

Ensuite, vous aurez besoin de modifier votre code afin que vous preniez l'appel AJAX vous-même et peut détecter lorsque 0 résultats reviennent:

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

2voto

Zappa Points 418

Si vous utilisez une source de données distante (comme une base de données MySQL, PHP, ou quoi que ce soit sur le côté serveur) il y a une couple d'autres cleaner façons de gérer une situation où il n'y a pas de données à envoyer au client (sans la nécessité pour tous les hacks ou code de base de l'INTERFACE utilisateur des modifications de code).

J'utilise PHP et MySQL comme ma source de données distante et JSON pour transmettre des informations entre eux. Dans mon cas, il me semblait pour obtenir jQuery erreurs d'exception si le JSON demande de ne pas obtenir une sorte de réponse du serveur, donc je l'ai trouvé plus facile de retourner un vide réponse JSON à partir du côté serveur quand il n'y a pas de données et de gérer la réponse du client à partir de là:

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

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

Une autre façon serait de revenir un drapeau dans la réponse du serveur pour indiquer qu'il n'y a pas d'appariement de données et effectuer des actions côté client basé sur la présence (ou la valeur) de l'indicateur dans la réponse. Dans ce cas, les serveurs réponse serait quelque chose comme:

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

Puis, sur la base de cet indicateur actions peuvent être exécutées côté client:

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

2voto

Guntram Points 71

Après l’initialisation de votre élément de saisie semi-automatique, définir les messages option si vous souhaitez utiliser la valeur par défaut s’étend sur indication de message :

NOTE: il s’agit d’une API expérimentale (non documentée). développeurs de jQuery UI étudient encore une solution complète pour la manipulation de chaînes et d’internationalisation.

0voto

Umar Malik Points 49

Après des heures à jouer, j’ai finalement trouvé une astuce pour afficher dans jQuery autocomplete. Regardez le code ci-dessus et il suffit d’ajouter une , dans mon cas et son style la valeur . Lors de la vérification de méthode de réussite rappel si le tableau renvoyé a `` . Si c’est là que vous allez, vous avez fait votre journée ! :)

0voto

Salman A Points 60620

Je ne vois pas pourquoi source de paramètre dans une fonction de rappel personnalisée est pas assez. En supposant que nous sommes à l'aide d'un JSON(P) service, il suffit de garder les points suivants à l'esprit:

Du côté serveur, le script doit produire JSON valide, même si aucun résultat n'est trouvé-et [] est JSON valide.

La documentation pour l' source paramètre suggère que:

Une réponse de rappel, qui s'attend à un seul argument: les données de suggérer à l'utilisateur. Ces données doivent être filtrés sur la base du fourni terme, et peut être dans un des formats décrits ci-dessus pour simple des données locales. Il est important lors de la prestation personnalisée de la source rappel pour gérer les erreurs lors de la demande. Vous devez toujours faire appel à la réponse de rappel, même si vous rencontrez une erreur. Cela garantit que le widget a toujours le bon état.

En gardant les deux points à l'esprit, les points suivants doivent être suffisants:

$("#autocomplete").autocomplete({
    source: function (request, response) {
        $.ajax({
            url: "http://example.com/service.json",
            data: {
                q: this.term
            },
            success: function (data, textStatus, jqXHR) {
                // data must be an array containing 0 or more items
                console.log("[SUCCESS] " + data.length + " item(s)");
                response(data);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                // triggered when AJAX failed because of, for example, malformed JSON
                console.log("[ERROR] n/a item(s)");
                response([]);
            }
        });
    }
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X