Wie kann ich die automatische Vervollständigung Plug-in-Ergebnisse individuell formatiert werden?
-
19-09-2019 - |
Frage
Ich bin mit der jQuery UI automatischen Vervollständigung Plug-in . Gibt es eine Möglichkeit zu markieren Suchzeichenfolge in Dropdown-Ergebnisse?
Zum Beispiel, wenn ich „foo bar“ als Daten haben, und ich geben "foo" Ich werde „ foo Bar“ in der Drop-down, wie diese:
Lösung
Ja, Sie können, wenn Sie Affen-Patch zur automatischen Vervollständigung.
In der Autocomplete-Widget in v1.8rc3 von jQuery UI enthalten ist, wird die Popup-Vorschläge in der _renderMenu Funktion des Autocomplete-Widget erstellt. Diese Funktion wird wie folgt definiert:
_renderMenu: function( ul, items ) {
var self = this;
$.each( items, function( index, item ) {
self._renderItem( ul, item );
});
},
Die _renderItem Funktion wird wie folgt definiert:
_renderItem: function( ul, item) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
},
Also, was Sie tun müssen, ist zu ersetzen, dass _renderItem fn mit Ihrem eigenen Schöpfung, die die gewünschte Wirkung erzeugt. Diese Technik, die eine interne Funktion in einer Bibliothek neu zu definieren, ich bin gekommen, ist zu lernen, genannt Affe-Patchen . Hier ist, wie ich es getan hätte:
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 );
};
}
Anruf dieser Funktion einmal in $(document).ready(...)
.
Nun, dies ist ein Hack, denn:
-
gibt es einen regulären Ausdruck obj für jedes Element in der Liste gemacht erstellt. Das regexp obj sollte für alle Einzelteile wiederverwendet werden.
-
gibt es keine CSS-Klasse für die Formatierung des fertigen Teils verwendet. Es ist ein Inline-Stil.
Dies bedeutet, wenn Sie mehrere autocompletes auf der gleichen Seite haben, sie würden alle die gleiche Behandlung erhalten. Ein CSS-Stil wäre das lösen.
... aber es zeigt die Haupttechnik, und es funktioniert für Ihre grundlegenden Anforderungen.
aktualisiert Arbeitsbeispiel: http://output.jsbin.com/qixaxinuhe
Um den Fall der Matchstrings zu erhalten, im Gegensatz zu dem Fall der eingegebenen Zeichen, verwenden Sie die folgende Zeile:
var t = item.label.replace(re,"<span style='font-weight:bold;color:Blue;'>" +
"$&" +
"</span>");
Mit anderen Worten, von dem ursprünglichen Startcode oben, müssen Sie nur this.term
mit "$&"
ersetzen.
Bearbeiten
Die oben genannten Änderungen alle Autocomplete-Widget auf der Seite. Wenn Sie nur eine ändern möchten, sehen diese Frage:
Wie * Patch nur ein * Beispiel von automatischer Vervollständigung auf einer Seite?
Andere Tipps
das auch funktioniert:
$.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 von @ Jörn Zaefferer und @ Cheeso Antworten.
Super hilfreich. Danke. +1.
Hier ist eine Light-Version, dass Sorten auf „String mit dem Begriff anfangen müssen“:
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();
jQueryUI 1.9.0 Änderungen wie _renderItem funktioniert.
Der folgende Code führt diese Änderung zu berücksichtigen und auch zeigt, wie ich Highlight Matching tat mit Jörn Zaefferer jQuery Autocomplete-Plugin. Es werden alle einzelnen Begriffe in der gesamten Suchbegriff markieren.
Seit dem Umzug zur Verwendung von Knockout und jqAuto Ich finde dies eine viel einfachere Art und Weise die Ergebnisse des Styling.
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();
});
Hier geht es, ein funktionelles 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>
Hope, das hilft
für eine noch einfachere Möglichkeit, versuchen Sie dies:
$('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)
});
}
Hier ist ein Aufguss von Ted de Koning-Lösung. Es umfasst:
- Case insensitive Suche
- Finding viele 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);
};
Hier ist eine Version, die keine regulären Ausdrücke erfordert und paßt mehrere Ergebnisse auf dem Etikett.
$.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);
};
Werfen Sie einen Blick auf die Combobox Demo beinhaltet es Ergebnishervorhebungen: http://jqueryui.com / demos / automatische Vervollständigung / # combobox
Die Regex in Gebrauch es befasst sich auch mit HTML-Ergebnisse.
Hier ist meine Version:
- Verwendet DOM-Funktionen anstelle von regulären Ausdrücke zu brechen / inject span-Tags
- Nur die angegebene zur automatischen Vervollständigung betroffen ist, nicht alle
- Kompatibel 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);
};
können Sie verwenden, um Code Folowing:
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 schafft eigene Widget, das _renderItem
ohne Überschreiben _renderItem
von Original-Plugin Prototyp außer Kraft setzen kann.
in meinem Beispiel auch gebrauchte ursprüngliche Funktion zu einem gewissen simplify Code machen
Es ist wichtig, was, wenn Sie an verschiedenen Orten mit unterschiedlichen Blick auf die automatische Vervollständigung verwenden Plugin wollen und wollen nicht, Ihren Code zu brechen.
Wenn Sie stattdessen die 3rd-Party-Plugin verwendet, hat es eine Highlight-Option: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions
(siehe die Registerkarte Optionen)
mehr Werte zu unterstützen, einfach nur 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>");