Partager via


Cet article a fait l'objet d'une traduction automatique.

À la pointe

Saisie par anticipation

Dino Esposito

Dino EspositoDepuis les débuts du Web, les pages la plupart disposent d'une boîte de recherche pour vous aider à trouver rapidement le contenu dans la page elle-même ou sur le site. Une fonction de recherche bien pensée s'avère indispensable pour les sites plus grands. Ceci aide les utilisateurs à trouver ce qu'ils veulent rapidement et facilement, sans passer par le plan du site et l'architecture.

Dans un site de shopping, par exemple, vous pouvez utiliser des chaînes de requête pour rechercher des produits, offres, ou nouvelles et alertes. Dans un site construit pour quelque chose comme une équipe de sport professionnel, la fonction de recherche doit être capable de creuser de nouvelles, résultats, nom de l'athlète, du bios et ainsi de suite. La structure de données sur laquelle une fonction de recherche a travailler n'est jamais évidente. Il est clairement spécifiques à l'application.

Au lieu de réinventer la roue à chaque fois, envisagez d'utiliser un moteur de recherche de texte intégral ad hoc comme Lucene.Net pour sauvegarder votre fonction de recherche. Un moteur comme Lucene.Net indexe un tas de documents basé sur chaîne et analyse une chaîne de requête donnée contre l'index. Ce faisant, le moteur vous permet de spécifier des combinaisons complexes de chaînes de requête. Pour beaucoup de pages et de sites, Lucene.Net est peut-être exagéré, mais ils ont encore besoin d'un type de recherche qui est plus intelligent que placer une interminable liste d'éléments dans une liste déroulante.

Cet article présentera un petit "framework" pour la saisie semi-automatique construite autour de Twitter typeahead.js. Ce cadre n'est pas magique, mais il simplifie vraiment à l'aide de la saisie semi-automatique dans les pages Web. L'aspect le plus alléchant de ce cadre est qu'il vous permet de combiner plusieurs ensembles de données de requête dans la même page et récupérer des informations distinctes mais connexes.

Mise en place de Typeahead.js

Pour cet article, je vais clarifier les bases de l'utilisation de typeahead dans un scénario réaliste, utilisez la version de typeahead vous trouverez sur NuGet lorsque vous tapez « typeahead », comme le montre Figure 1. Lorsque vous Google recherchez d'images typeahead, vous risquez en références plus anciennes, les anciens fichiers JavaScript ou les versions juste fourchues du code projet original. Documentation est trompeuse, aussi bien.

le Package NuGet pour Twitter Typeahead.js
Figure 1 le Package NuGet pour Twitter Typeahead.js

Le fichier bundle contient tous les paquets qui composent la bibliothèque, y compris le moteur Bloodhound pour gérer les notes sur le navigateur local. Pour mettre en place une page Web ou Razor vue d'utiliser typeahead.js, vous juste devez la syntaxe familière à jQuery et activez le plug-in sur le champ de saisie sélectionné. Voici un exemple :

< forment action="@Url.Action ("requête","Home")" méthode = « post » >

< input type = « hidden » ID = « queryCode » nom = « queryCode » / >

< input type = « text » nom = « queryString » ID = « queryString » >

< id bouton = « queryButton » type = « submit » > Téléchargez < / bouton >

< / font >

<form action="@Url.Action("Query", "Home")" method="post">
  <input type="hidden" id="queryCode" name="queryCode" />
    <input type="text" name="queryString" id="queryString">
    <button id="queryButton" type="submit">Get</button>
</form>

Il est important de noter que pour pouvoir utiliser la saisie semi-automatique sur une page Web pour quelque chose d'utile, vous devez également un terrain de copain caché pour recueillir une sorte d'ID unique pour l'indicateur sélectionné. Il existe de nombreux scénarios dans lesquels vous pouvez envisager l'utilisation d'un champ de saisie semi-automatique. Le scénario, par que je suis intéressé utilise la saisie semi-automatique en remplacement d'une liste déroulante autrement sans fin. Il permet léger, recherche Bing-style dans votre site, sans nécessiter l'aide de moteurs de texte intégral comme Lucene.Net.

Code de script dans la vue

Pour utiliser typeahead.js, référence jQuery 1.9.1 ou supérieur et le script typeahead. La quantité minimale de code vous que vous aurez besoin de l'avis êtes affiché ici :

$('#queryString').typeahead(
  null,
  {
    displayKey: 'value',
    source: hints.ttAdapter()
  }
});

Ce faisant, vous prenez tous les paramètres par défaut et indiquer au moteur d'utiliser la propriété value dans les données retournées pour remplir la liste déroulante. Une propriété nommée value est censée pour exister dans n'importe quelles données que vous filtrez. En théorie, vous pouvez configurer la saisie semi-automatique sur n'importe quel tableau de données JavaScript. Dans la pratique, cependant, la saisie semi-automatique est logique surtout lorsque les données sont téléchargées à partir d'une source distante.

Téléchargement à partir d'une source éloignée pose beaucoup de questions — même -­stratégie de navigateur d'origine, le préchargement et la mise en cache — pour n'en nommer que quelques-uns. Twitter typeahead.js est livré avec un moteur de suggestion nommé Bloodhound. Ceci en toute transparence accomplit l'essentiel de ce travail pour vous. Si vous obtenez le fichier JavaScript de NuGet, vous pouvez commencer juste remettre en limier sans se soucier de son téléchargement et d'installation. La variable de conseils dans l'extrait de code précédent résulte de l'initialisation suivante et plutôt standard du chien de chasse :

var hints = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  remote: "/hint/s?query=%QUERY"
});
hints.initialize();

Notez l'attribut distant. C'est juste le point de terminaison serveur chargé de retourner les indices pour afficher dans la liste déroulante. Notez également la syntaxe % QUERY. Ceci indique la chaîne dans le champ d'entrée étant envoyé au serveur pour trouver des indices. En d'autres termes, % QUERY est un espace réservé pour le texte est dans le champ de saisie. Par défaut, typeahead.js commence à devenir conseils dès que vous tapez un caractère unique. Si vous voulez attendre pour les caractères à être dans la mémoire tampon avant le début de la saisie semi-automatique, puis ajoutez un objet de paramètres comme le premier argument du plug-in :

$('#queryString').typeahead(
  {
    minLength: 2
  },
  {
    displayKey: 'value',
    source: hints.ttAdapter()
  }
});

Lorsque le tampon est assez complet pour lancer des appels distants, Bloodhound commence à travailler. Il télécharge les données JSON et l'adapte pour l'affichage. À ce stade, vous possédez une à peine travail semi-automatique moteur qui s'ouvre aux suggestions basées sur une logique vous avez sur le serveur. Cependant, il y a beaucoup plus à faire avant de pouvoir utiliser la saisie semi-automatique efficacement dans une page réelle.

Utiliser Typeahead.js avec Bootstrap

Tout suffisamment complexe plug-in a besoin d'un peu de CSS à l'air sympa. TypeAhead.js ne fait pas exception. Le plug-in est livré avec sa propre interface utilisateur par défaut, mais vous pouvez appliquer quelques corrections, surtout si vous utilisez Twitter bootstrap. Vous pouvez également personnaliser certains attributs visuels, tels que les couleurs et le rembourrage. La figure 2 répertorie certaines classes CSS, vous pouvez utiliser pour personnaliser le look-and-feel de la composante typeahead.js.

Figure 2 les Classes CSS Edit afin de personnaliser le composant Typeahead.js

Classe CSS Description
Twitter-typeahead Le champ de saisie lorsque l'utilisateur tape des conseils des styles.
TT-hint Les styles de texte qui représente le delta entre ce que vous avez tapé et le premier indice. Cette classe est utilisée uniquement lorsque la propriété de l'indication est définie sur true (false par défaut).
menu-déroulant-TT Styles le popup menu déroulant où les conseils sont répertoriés.
TT-curseur Styles mis en évidence les suggestions dans la liste déroulante.
TT-highlight Les styles de la partie du texte qui correspond à la chaîne de requête.

Figure 3 donne une idée de ce que vous pouvez sortir des classes CSS personnalisées. Vous pouvez également personnaliser le comportement dans l'ensemble de plug-in d'un point de vue fonctionnel.

CSS personnalisé Classes peuvent accomplir des effets différents pour votre application
Figure 3 CSS personnalisé Classes peuvent accomplir des effets différents pour votre application

Ajouter une logique côté Client

Un champ de saisie semi-automatique est plus rapide que n'importe quel long dropdown. Lorsque le nombre d'éléments parmi lesquels choisir est dans les centaines, cependant, n'importe quelle liste déroulante classique est lente. Par conséquent, si vous prévoyez d'utiliser le champ de saisie semi-automatique pour sélectionner une valeur spécifique — dire, le nom d'un produit ou d'un client — puis une plaine typeahead.js plug-in n'est pas suffisant. Certains code de script supplémentaire n'est requis que se lie à l'événement sélectionné de plug-in :

$('#queryString').on('typeahead:selected', 
  function (e, datum) {
  $("#queryCode").val(datum.id);
});

Le principal avantage de saisie semi-automatique est utilisateurs tapent un nom intelligible et le système récupère le code unique affiliée ou ID. Cette fonction doit être explicitement codé. Dans le gestionnaire de l'événement sélectionné, vous récupérez les informations d'ID de l'objet de référence et de stockez en toute sécurité dans un champ masqué. Lorsque le formulaire auquel appartiennent les champs de saisie semi-automatique est affiché, l'ID sélectionné est affiché, aussi bien. Le format de l'objet de référence — l'élément de données sélectionné dans la liste déroulante — repose sur le format des données que vous recevez du côté serveur.

Qu'en est-il le texte affiché dans le champ de saisie ? Dans ce scénario, vous avez probablement pas besoin d'avoir n'importe quel texte significatif apparaît dans le champ d'entrée. L'entrée pertinente pour d'autres opérations, c'est ce que vous stockez dans le champ masqué. Ce que vous affichez là, c'est à vous. Juste des avis si vous spécifiez dans les paramètres de plug-in, une propriété de displayKey, parce qu'alors la valeur de cette propriété est automatiquement affichée dans le champ d'entrée. En tout cas, vous pouvez définir n'importe quelle valeur par programme :

$("#queryString").val(datum.label);

Dans certains cas, la zone de texte de saisie semi-automatique est le seul élément dans le formulaire HTML. Cela signifie que vous pouvez traiter toutes les données sélectionnées dès qu'il est sélectionné. En ajoutant la ligne suivante au gestionnaire d'événements sélectionnés typeahead.js, vous simulez un clic sur le bouton envoyer du formulaire :

$("#queryButton").click();

Supposons qu'un utilisateur commence à taper dans le champ de saisie, provoque la liste déroulante Afficher et puis arrête de taper sans faire de sélection. Que faire lorsqu'il repasse en tapant ? Naturellement, vous lui laisserait taper à nouveau jusqu'à ce qu'il effectue une sélection. Une fois que l'utilisateur effectue une sélection, un code a été stocké donc lors de l'édition reprend cette sélection doit être annulée. Vous avez besoin d'une variable locale pour y parvenir :

var typeaheadItemSelected = false;
$('#queryString').on('typeahead:selected', function (e, datum) {
  $("#queryCode").val(datum.id);
  typeaheadItemSelected = true;
});

Vous devez également un gestionnaire pour l'événement de focus du champ d'entrée pour réinitialiser toutes les données stockées :

$('#queryString').on('input', function () {
  if (typeaheadItemSelected) {
    typeaheadItemSelected = false;
    $('#queryString').val(''); 
    $("#queryCode").val('');
  }
});

Le but ultime de cette logique supplémentaire côté client doit s'assurer que les œuvres de champ de saisie semi-automatique identique à une liste déroulante.

Le côté serveur de saisie semi-automatique

Tout ce qui peut faire n'importe quel code côté client dépend strictement les données renvoyées par le serveur. Au minimum, le point de terminaison de serveur est juste une URL qui renvoie des données JSON. Une fois que vous avez un point de terminaison qui propose une collection d'objets Product, par exemple, vous pouvez utiliser la propriété displayKey de typeahead.js pour effectuer une sorte de liaison de données sur la liste déroulante des conseils. Dans sa forme la plus simple, une méthode qui retourne JSON contrôleur peut ressembler à ceci :

public JsonResult P(string query)
{
  var productHints = _service.GetMatchingProducts(query);
  return Json(productHints, JsonRequestBehavior.AllowGet);
}

Si le champ de saisie semi-automatique est censé afficher des conseils pour les éléments de données homogènes, c'est une approche idéale. Côté client, en fait, vous pouvez exploiter le mécanisme de création de modèles intégré typeahead.js et agencez facilement des vues personnalisées de suggestion :

$('#queryString').typeahead(
null,
{
  templates: {
    suggestion: Handlebars.compile('<b>({{Id}}</b>: {{notes}}')
  },
  source: hints.ttAdapter()
});

La propriété de modèles remplace displayKey et définit une disposition personnalisée pour le contenu de la liste déroulante. La liste déroulante dans Figure 3 résulte de l'extrait de code précédent. Pour trier un modèle, vous pouvez utiliser un moteur de template ad hoc comme le guidon (handlebarsjs.com). Vous devez lier séparément guidon au projet de typeahead.js. L'utilisation de guidons est facultative. Vous pouvez toujours formater un modèle HTML par l'intermédiaire de manuelle du code JavaScript ou même retourner un objet côté serveur avec HTML préformaté.

Les choses deviennent plus délicat lorsque votre saisie semi-automatique est censé reprendre les conseils hétérogènes, tels que les produits ou l'offre. Dans ce cas, vous devez retourner un tableau d'un type de données intermédiaire qui contient suffisamment d'informations pour l'utilisateur de choisir. L'auto-complètement que vous obtenez avec cet article vous propose une classe de base du AutoCompleteItem, comme illustré ici :

public class AutoCompleteItem
{
  public String label { get; set; }
  public String id { get; set; }
  public String value { get; set; }
}

La propriété id contient un identifiant unique. Lors de la validation, c'est significatif pour le contrôleur de récepteur. Il est généralement composée de deux feuilles — l'ID réel et un identificateur unique correspondant à l'ID de l'un des ensembles de données (produits ou offres) éventuellement retourné dans la requête. La valeur de la propriété est le contenu de la chaîne à afficher dans la liste déroulante. L'autre propriété est une propriété de sorte de cargaison pour tout ce que vous pourriez avoir besoin. La propriété value peut également contenir des chaînes HTML serveur-côté-arrangé pour les mises en page personnalisées de suggestion. Le code côté serveur est également responsable de l'exécution de requêtes tout requis et masser les données dans une collection d'objets AutoCompleteItem.

Récapitulation

Facilité d'utilisation est la plus importante de tous les jours dans des sites Web modernes. Il est le bienvenu dans la face publique du site, mais il est encore plus critique dans le site Web où l'information réelle est insérée back-ends. Sur la côté de l'un de mes sites Web admin, j'ai eu une fois une liste déroulante avec plus de 700 Articles. Cela a fonctionné, mais il a été lent. Je l'ai remplacé avec la saisie semi-automatique et maintenant il est incroyablement rapide. Je me suis arrangé un projet GitHub pour cela et d'autres services publics à bit.ly/1zubJea.


Dino Esposito est le co-auteur de « Microsoft .NET : Conception d'Applications pour l'entreprise » (Microsoft Press, 2014) et "programmation ASP.NET MVC 5" (Microsoft Press, 2014). Un spécialiste technique de Microsoft .NET Framework et les plates-formes Android à JetBrains et lors des événements de l'industrie dans le monde entier, Esposito partage sa vision du logiciel à software2cents.wordpress.com et sur Twitter à twitter.com/despos.

Grâce à l'expert technique suivante pour l'examen de cet article : Jon Arne Saeteras