wake-up-neo.com

Wie kann ich die Ergebnisse des Autocomplete-Plug-Ins benutzerdefiniert formatieren?

Ich verwende das jQuery UI Autocomplete-Plug-in . Gibt es eine Möglichkeit, die Suchzeichenfolge in Dropdown-Ergebnissen hervorzuheben?

Wenn ich beispielsweise "foo bar" als Daten habe und "foo" eingebe, wird in der Dropdown-Liste " foo bar" angezeigt. so was:

“Breakfast” appears after “Bre” is typed with “Bre” having a bold type and “akfast” having a light one.

167
dev.e.loper

Autocomplete with live suggestion

Ja, das kannst du, wenn du das Affen-Patch automatisch vervollständigst.

In dem in Version 1.8rc3 der jQuery-Benutzeroberfläche enthaltenen Widget für die automatische Vervollständigung wird das Popup der Vorschläge in der Funktion _renderMenu des Widgets für die automatische Vervollständigung erstellt. Diese Funktion ist folgendermaßen definiert:

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

Die Funktion _renderItem ist folgendermaßen definiert:

_renderItem: function( ul, item) {
    return $( "<li></li>" )
        .data( "item.autocomplete", item )
        .append( "<a>" + item.label + "</a>" )
        .appendTo( ul );
},

Sie müssen also das _renderItem fn durch Ihre eigene Kreation ersetzen, die den gewünschten Effekt erzeugt. Diese Technik, mit der ich eine interne Funktion in einer Bibliothek neu definiert habe, heißt monkey-patching . So habe ich es gemacht:

  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,"<span style='font-weight:bold;color:Blue;'>" + 
                  this.term + 
                  "</span>");
          return $( "<li></li>" )
              .data( "item.autocomplete", item )
              .append( "<a>" + t + "</a>" )
              .appendTo( ul );
      };
  }

Rufen Sie diese Funktion einmal in $(document).ready(...) auf.

Das ist ein Hack, weil:

  • für jedes Element in der Liste wird ein regulärer Ausdruck erstellt. Dieses Regexp-Objekt sollte für alle Elemente wiederverwendet werden.

  • für die Formatierung des fertigen Teils wird keine CSS-Klasse verwendet. Es ist ein Inline-Stil.
    Das bedeutet, wenn Sie mehrere Autovervollständigungen auf derselben Seite hatten, würden sie alle die gleiche Behandlung erhalten. Ein CSS-Stil würde das lösen.

... aber es zeigt die Haupttechnik und entspricht Ihren Grundanforderungen.

alt text

aktualisiertes Arbeitsbeispiel: http://output.jsbin.com/qixaxinuhe


Verwenden Sie diese Zeile, um die Groß- und Kleinschreibung der Übereinstimmungszeichenfolgen beizubehalten, anstatt die Groß- und Kleinschreibung der eingegebenen Zeichen zu verwenden:

var t = item.label.replace(re,"<span style='font-weight:bold;color:Blue;'>" + 
          "$&" + 
          "</span>");

Mit anderen Worten, beginnend mit dem obigen Originalcode müssen Sie nur this.term Durch "$&" Ersetzen.


[~ # ~] edit [~ # ~]
Die obigen Änderungen every Widget auf der Seite automatisch vervollständigen. Wenn Sie nur einen ändern möchten, sehen Sie sich diese Frage an:
Wie kann * nur eine * Instanz von Autocomplete auf einer Seite gepatcht werden?

231
Cheeso

das funktioniert auch:

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

eine Kombination aus @ Jörn Zaefferer und @ Cheesos Antworten.

65
Raj

Super hilfsbereit Vielen Dank. +1.

Hier ist eine Light-Version, die nach "String muss mit dem Begriff beginnen" sortiert ist:

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();
8
orolo

Hier ist ein funktionierendes vollständiges Beispiel:

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Autocomplete - jQuery</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css">
</head>
<body>
<form id="form1" name="form1" method="post" action="">
  <label for="search"></label>
  <input type="text" name="search" id="search" />
</form>

<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<script>
$(function(){

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


var availableTags = [
    "JavaScript",
    "ActionScript",
    "C++",
    "Delphi",
    "Cobol",
    "Java",
    "Ruby",
    "Python",
    "Perl",
    "Groove",
    "LISP",
    "Pascal",
    "Assembly",
    "Cliper",
];

$('#search').autocomplete({
    source: availableTags,
    minLength: 3
});


});
</script>
</body>
</html>

Hoffe das hilft

6
Fabio Nolasco

jQueryUI 1.9.0 ändert die Funktionsweise von _renderItem.

Der folgende Code berücksichtigt diese Änderung und zeigt auch, wie ich mit dem jQuery Autocomplete-Plugin von Jörn Zaefferer das Highlight-Matching durchgeführt habe. Es werden alle einzelnen Begriffe im gesamten Suchbegriff hervorgehoben.

Seit ich Knockout und jqAuto benutze, ist es mir viel leichter gefallen, die Ergebnisse zu stylen.

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 string of terms to highlight
      var keywords = $.trim(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,  
         '<span class="ui-menu-item-highlight">$1</span>');

      return $("<li>")
         .append($("<a>").html(output))
         .appendTo(ul);
   };
};

$(function () {
   monkeyPatchAutocomplete();
});
6
79IT

Hier ist eine Wiederholung von Ted de Konings Lösung. Es enthält :

  • Suche ohne Berücksichtigung der Groß-/Kleinschreibung
  • Finden vieler Vorkommen der gesuchten Zeichenfolge
$.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 string
    var iPointer    = 0;
    var sOutput     = '';

    //Change style here
    var sPrefix     = '<strong style="color:#3399FF">';
    var sSuffix     = '</strong>';

    //Find all occurences positions
    tTemp = item.label.toLowerCase().split(this.term.toLowerCase());
    var CharCount = 0;
    tTemp[-1] = '';
    for(i=0;i<tTemp.length;i++){
        CharCount += tTemp[i-1].length;
        tStrPos[i] = CharCount + (i * iTermLength) + tTemp[i].length
    }

    //Apply style
    i=0;
    if(tStrPos.length > 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 $("<li></li>")
        .data("item.autocomplete", item)
        .append("<a>" + sOutput + "</a>")
        .appendTo(ul);
};
3
Pierre

versuchen Sie es noch einfacher:

$('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, ("<span style='font-weight:bold;color:green;'>")  + matchNew +    ("</span>"));

    $(this).html(text)
});
  }
3
Aaron

Hier ist eine Version, die keine regulären Ausdrücke erfordert und mit mehreren Ergebnissen in der Bezeichnung übereinstimmt.

$.ui.autocomplete.prototype._renderItem = function (ul, item) {
            var highlighted = item.label.split(this.term).join('<strong>' + this.term +  '</strong>');
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a>" + highlighted + "</a>")
                .appendTo(ul);
};
2
Ted de Koning

Schauen Sie sich die Combobox-Demo an. Sie enthält die Hervorhebung der Ergebnisse: http://jqueryui.com/demos/autocomplete/#combobox

Der dort verwendete reguläre Ausdruck behandelt auch HTML-Ergebnisse.

1
Jörn Zaefferer

Hier ist meine Version:

  • Verwendet DOM-Funktionen anstelle von RegEx, um Strings zu unterbrechen/Span-Tags einzufügen
  • Nur die angegebene Autovervollständigung ist betroffen, nicht alle
  • Funktioniert mit UI-Version 1.9.x
function highlightText(text, $node) {
    var searchText = $.trim(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 = $("<a></a>").text(item.label);
    highlightText(this.term, $a);
    return $("<li></li>").append($a).appendTo(ul);
};

Markieren Sie das Beispiel mit dem passenden Text

1
Salman A

sie können folgenden Code verwenden:

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

und Logik:

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

es erstellt ein benutzerdefiniertes Widget, das _renderItem überschreiben kann, ohne _renderItem des ursprünglichen Plugin-Prototyps zu überschreiben.

in meinem Beispiel wurde auch die ursprüngliche Renderfunktion verwendet, um den Code zu vereinfachen

es ist wichtig, dass Sie das Plugin an verschiedenen Stellen mit unterschiedlicher Ansicht der Autovervollständigung verwenden und Ihren Code nicht beschädigen möchten.

1
E.Monogarov

Um mehrere Werte zu unterstützen, fügen Sie einfach folgende Funktion hinzu:

function getLastTerm( term ) {
  return split( term ).pop();
}

var t = String(item.value).replace(new RegExp(getLastTerm(this.term), "gi"), "<span class='ui-state-highlight'>$&</span>");
0
ZaieN

Wenn Sie stattdessen das Plugin eines Drittanbieters verwenden, gibt es eine Hervorhebungsoption: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions

(siehe Registerkarte Optionen)

0
Brian Luft