Comment puis-je personnaliser les résultats du plug-in de saisie semi-automatique?

J’utilise le plug-in de saisie semi-automatique de l’interface utilisateur jQuery . Existe-t-il un moyen de mettre en évidence la séquence de caractères de recherche dans les résultats déroulants?

Par exemple, si j’ai “foo bar” comme données et que je tape “foo”, j’aurai ” foo bar” dans la liste déroulante, comme ceci:

“Breakfast” apparaît après que “Bre” a été saisi avec “Bre” ayant un caractère gras et “akfast” ayant un caractère clair.

Autocomplet avec suggestion en direct

Oui, vous pouvez le faire si vous complétez automatiquement le patch de singe.

Dans le widget autocomplete inclus dans la v1.8rc3 de l’interface utilisateur jQuery, la fenêtre contextuelle des suggestions est créée dans la fonction _renderMenu du widget autocomplete. Cette fonction est définie comme ceci:

_renderMenu: function( ul, items ) { var self = this; $.each( items, function( index, item ) { self._renderItem( ul, item ); }); }, 

La fonction _renderItem est définie comme suit:

 _renderItem: function( ul, item) { return $( "
  • " ) .data( "item.autocomplete", item ) .append( "" + item.label + "" ) .appendTo( ul ); },

    Donc, ce que vous devez faire est de remplacer ce fn _renderItem par votre propre création qui produit l’effet désiré. Cette technique, qui consiste à redéfinir une fonction interne dans une bibliothèque, que je viens d’apprendre, s’appelle monkey-patching . Voici comment je l’ai fait:

      function monkeyPatchAutocomplete() { // don't really need this, but in case I did, I could store it and chain var oldFn = $.ui.autocomplete.prototype._renderItem; $.ui.autocomplete.prototype._renderItem = function( ul, item) { var re = new RegExp("^" + this.term) ; var t = item.label.replace(re,"" + this.term + ""); return $( "
  • " ) .data( "item.autocomplete", item ) .append( "" + t + "" ) .appendTo( ul ); }; }

    Appelez cette fonction une fois dans $(document).ready(...) .

    Maintenant, c’est un hack parce que:

    • une expression rationnelle est créée pour chaque élément affiché dans la liste. Cette expression rationnelle devrait être réutilisée pour tous les éléments.

    • il n’y a pas de classe css utilisée pour le formatage de la pièce complétée. C’est un style en ligne.
      Cela signifie que si plusieurs autocompletes se trouvaient sur la même page, ils recevraient tous le même traitement. Un style CSS permettrait de résoudre ce problème.

    … mais il illustre la technique principale et cela fonctionne pour vos besoins de base.

    texte alt

    exemple de travail mis à jour: http://output.jsbin.com/qixaxinuhe


    Pour conserver la casse des chaînes de correspondance, au lieu d’utiliser la casse des caractères saisis, utilisez cette ligne:

     var t = item.label.replace(re,"" + "$&" + ""); 

    En d’autres termes, à partir du code d’origine ci-dessus, il vous suffit de remplacer this.term par "$&" .


    MODIFIER
    Ce qui précède modifie chaque widget de saisie semi-automatique sur la page. Si vous souhaitez en changer qu’un seul, consultez cette question:
    Comment patcher * une seule * instance de saisie semi-automatique sur une page?

    cela fonctionne aussi:

      $.ui.autocomplete.prototype._renderItem = function (ul, item) { item.label = item.label.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(this.term) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1"); return $("
  • ") .data("item.autocomplete", item) .append("" + item.label + "") .appendTo(ul); };

    une combinaison des réponses de @ Jörn Zaefferer et @ Cheeso.

    Super utile Je vous remercie. +1.

    Voici une version allégée qui sortinge sur “Ssortingng doit commencer par le terme”:

     function hackAutocomplete(){ $.extend($.ui.autocomplete, { filter: function(array, term){ var matcher = new RegExp("^" + term, "i"); return $.grep(array, function(value){ return matcher.test(value.label || value.value || value); }); } }); } hackAutocomplete(); 

    Voilà, un exemple fonctionnel complet:

         Autocomplete - jQuery    

    J’espère que cela t’aides

    jQueryUI 1.9.0 modifie le fonctionnement de _renderItem.

    Le code ci-dessous prend en compte ce changement et montre également comment je faisais la mise en correspondance des mises en évidence à l’aide du plugin JQuery Autocomplete de Jörn Zaefferer. Il mettra en évidence tous les termes individuels dans le terme de recherche global.

    Depuis que je me suis mis à utiliser Knockout et jqAuto, j’ai trouvé que c’était un moyen beaucoup plus facile de styliser les résultats.

     function monkeyPatchAutocomplete() { $.ui.autocomplete.prototype._renderItem = function (ul, item) { // Escape any regex syntax inside this.term var cleanTerm = this.term.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); // Build pipe separated ssortingng of terms to highlight var keywords = $.sortingm(cleanTerm).replace(' ', ' ').split(' ').join('|'); // Get the new label text to use with matched terms wrapped // in a span tag with a class to do the highlighting var re = new RegExp("(" + keywords + ")", "gi"); var output = item.label.replace(re, '$1'); return $("
  • ") .append($("").html(output)) .appendTo(ul); }; }; $(function () { monkeyPatchAutocomplete(); });
  • pour un moyen encore plus facile, essayez ceci:

     $('ul: li: a[class=ui-corner-all]').each (function (){ //grab each text value var text1 = $(this).text(); //grab user input from the search box var val = $('#s').val() //convert re = new RegExp(val, "ig") //match with the converted value matchNew = text1.match(re); //Find the reg expression, replace it with blue coloring/ text = text1.replace(matchNew, ("") + matchNew + ("")); $(this).html(text) }); } 

    Voici un résumé de la solution de Ted de Koning. Il comprend :

    • Recherche insensible à la casse
    • Trouver de nombreuses occurrences de la chaîne recherchée
     $.ui.autocomplete.prototype._renderItem = function (ul, item) { var sNeedle = item.label; var iTermLength = this.term.length; var tStrPos = new Array(); //Positions of this.term in ssortingng var iPointer = 0; var sOutput = ''; //Change style here var sPrefix = ''; var sSuffix = ''; //Find all occurences positions tTemp = item.label.toLowerCase().split(this.term.toLowerCase()); var CharCount = 0; tTemp[-1] = ''; for(i=0;i 0){ while(iPointer < sNeedle.length){ if(i<=tStrPos.length){ //Needle if(iPointer == tStrPos[i]){ sOutput += sPrefix + sNeedle.substring(iPointer, iPointer + iTermLength) + sSuffix; iPointer += iTermLength; i++; } else{ sOutput += sNeedle.substring(iPointer, tStrPos[i]); iPointer = tStrPos[i]; } } } } return $("
  • ") .data("item.autocomplete", item) .append("" + sOutput + "") .appendTo(ul); };

    Voici une version qui ne nécessite aucune expression régulière et correspond à plusieurs résultats dans l’étiquette.

     $.ui.autocomplete.prototype._renderItem = function (ul, item) { var highlighted = item.label.split(this.term).join('' + this.term + ''); return $("
  • ") .data("item.autocomplete", item) .append("" + highlighted + "") .appendTo(ul); };

    Jetez un coup d’œil à la démonstration de combobox, qui comprend la mise en évidence des résultats: http://jqueryui.com/demos/autocomplete/#combobox

    La regex utilisée ici traite également des résultats HTML.

    Voici ma version:

    • Utilise les fonctions DOM au lieu de RegEx pour casser les balises de chaînes / d’injection
    • Seule la saisie semi-automatique spécifiée est affectée, pas toutes
    • Fonctionne avec l’interface utilisateur version 1.9.x
     function highlightText(text, $node) { var searchText = $.sortingm(text).toLowerCase(), currentNode = $node.get(0).firstChild, matchIndex, newTextNode, newSpanNode; while ((matchIndex = currentNode.data.toLowerCase().indexOf(searchText)) >= 0) { newTextNode = currentNode.splitText(matchIndex); currentNode = newTextNode.splitText(searchText.length); newSpanNode = document.createElement("span"); newSpanNode.className = "highlight"; currentNode.parentNode.insertBefore(newSpanNode, currentNode); newSpanNode.appendChild(newTextNode); } } $("#autocomplete").autocomplete({ source: data }).data("ui-autocomplete")._renderItem = function (ul, item) { var $a = $("").text(item.label); highlightText(this.term, $a); return $("
  • ").append($a).appendTo(ul); };

    Mettez en surbrillance l’exemple de texte correspondant

    vous pouvez utiliser le code suivant:

    lib:

     $.widget("custom.highlightedautocomplete", $.ui.autocomplete, { _renderItem: function (ul, item) { var $li = $.ui.autocomplete.prototype._renderItem.call(this,ul,item); //any manipulation with li return $li; } }); 

    et logique:

     $('selector').highlightedautocomplete({...}); 

    Il crée un widget personnalisé qui peut remplacer _renderItem sans écraser _renderItem du prototype de plug-in d’origine.

    dans mon exemple également utilisé la fonction de rendu d’origine pour certains simplifier le code

    c’est important si vous voulez utiliser un plug-in à différents endroits avec une vue de saisie semi-automatique différente et ne voulez pas casser votre code.

    Si vous utilisez plutôt le plug-in tiers, il comporte une option de mise en évidence: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions

    (voir l’onglet Options)

    Pour supporter plusieurs valeurs, ajoutez simplement la fonction suivante:

     function getLastTerm( term ) { return split( term ).pop(); } var t = Ssortingng(item.value).replace(new RegExp(getLastTerm(this.term), "gi"), "$&");