JQuery UI Otomatik Tamamlama eklentisini kullanıyorum . Açılan sonuçlarda arama karakteri sırasını vurgulamanın bir yolu var mı?
Örneğin, veri olarak “foo bar” varsa ve “foo” yazarsam , açılır menüde “ foo bar” ı alırım , şöyle:
JQuery UI Otomatik Tamamlama eklentisini kullanıyorum . Açılan sonuçlarda arama karakteri sırasını vurgulamanın bir yolu var mı?
Örneğin, veri olarak “foo bar” varsa ve “foo” yazarsam , açılır menüde “ foo bar” ı alırım , şöyle:
Yanıtlar:
Evet, maymun yama otomatik tamamlama yaparsanız yapabilirsiniz.
JQuery UI'nin v1.8rc3'ünde bulunan otomatik tamamlama widget'ında, otomatik tamamlama widget'ının _renderMenu işlevinde öneriler açılır. Bu işlev şu şekilde tanımlanır:
_renderMenu: function( ul, items ) {
var self = this;
$.each( items, function( index, item ) {
self._renderItem( ul, item );
});
},
_RenderItem işlevi şu şekilde tanımlanır:
_renderItem: function( ul, item) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
},
Yapmanız gereken şey, _renderItem fn yerine istediğiniz efekti üreten kendi yaratımınızla değiştirmek. Bu tekniğe, bir kütüphanede dahili bir işlevi yeniden tanımlayarak, öğrendiğim maymun yaması denir . İşte böyle yaptım:
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 );
};
}
Bu işlevi bir kez ara $(document).ready(...)
.
Şimdi, bu bir hack, çünkü:
listede oluşturulan her öğe için bir regexp nesnesi oluşturulur. Bu normal ifade nesnesinin tüm öğeler için yeniden kullanılması gerekir.
tamamlanan parçanın biçimlendirilmesinde kullanılan bir css sınıfı yoktur. Satır içi bir stil.
Bu, aynı sayfada birden fazla otomatik tamamlamanız varsa, hepsinin aynı işlemi göreceği anlamına gelir. Bir css stili bunu çözerdi.
... ancak ana tekniği gösterir ve temel gereksinimleriniz için çalışır.
güncellenmiş çalışma örneği: http://output.jsbin.com/qixaxinuhe
Yazılan karakterlerin durumunu kullanmak yerine, eşleme dizelerinin durumunu korumak için şu satırı kullanın:
var t = item.label.replace(re,"<span style='font-weight:bold;color:Blue;'>" +
"$&" +
"</span>");
Başka bir deyişle, yukarıda orijinal kodundan başlayarak, sadece değiştirmeniz gerekiyor this.term
ile "$&"
.
EDIT
Yukarıdaki sayfadaki tüm otomatik tamamlama widget'larını değiştirir . Yalnızca bir tanesini değiştirmek istiyorsanız, şu soruya bakın:
Bir sayfada Otomatik Tamamlama * nın yalnızca bir * örneğini nasıl yamalatırsınız?
var re = new RegExp(this.term, "i");
Harika gönderi!
bu da işe yarar:
$.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);
};
@ Jörn Zaefferer ve @ Cheeso'nun yanıtlarının bir kombinasyonu.
$().autocomplete()
Süper yararlı. Teşekkür ederim. +1.
"String" terimi ile başlamalıdır "şeklinde sıralanan hafif bir sürüm:
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();
İşte fonksiyonel tam bir örnek:
<!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>
Bu yardımcı olur umarım
jQueryUI 1.9.0 _renderItem'in çalışma şeklini değiştirir.
Aşağıdaki kod bu değişikliği dikkate alır ve ayrıca nasıl Jörn Zaefferer'ın jQuery Autocomplete eklentisi kullanarak vurgu eşleme yaptığını gösterir. Genel arama terimindeki tüm ayrı terimleri vurgulayacaktır.
Knockout ve jqAuto kullanmaya başladığımdan beri, sonuçları şekillendirmenin çok daha kolay bir yolunu buldum.
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();
});
.jqAutocompleteMatch { font-weight: bold; }
this.term
Herhangi bir işlem yapmadan önce forgegex'ten kaçmak için bazı mantık kullanılmalıdır. Bunu nasıl yapacağınıza dair birçok yanıttan biri olarak Javascript normal ifadesinde kullanmak için Escape dizesi konusuna bakın .
daha da kolay bir yol için şunu deneyin:
$('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)
});
}
İşte Ted de Koning'in çözümünün yeniden canlandırılması. O içerir :
$.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);
};
Burada, normal ifadeler gerektirmeyen ve etiketteki birden çok sonuçla eşleşen bir sürüm var.
$.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);
};
Combobox demosuna bir göz atın, sonuç vurgulamayı içerir: http://jqueryui.com/demos/autocomplete/#combobox
Orada kullanılan regex ayrıca html sonuçları ile ilgilenir.
İşte benim sürüm:
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);
};
aşağıdaki kodu kullanabilirsiniz:
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;
}
});
ve mantık:
$('selector').highlightedautocomplete({...});
orijinal eklenti prototipinin _renderItem
üzerine yazmadan geçersiz kılabilecek özel widget oluşturur _renderItem
.
benim örneğimde bazı kodları basitleştirmek için orijinal render fonksiyonu da kullanıldı
eklentiyi farklı otomatik tamamlama görünümüne sahip farklı yerlerde kullanmak ve kodunuzu kırmak istemiyorsanız önemlidir.
Bunun yerine 3. taraf eklentisini kullanırsanız, bir vurgulama seçeneği vardır: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions
(Seçenekler sekmesine bakın)