ฉันใช้jQuery UI การเติมข้อความอัตโนมัติ Plug-in มีวิธีการเน้นลำดับอักขระการค้นหาในผลลัพธ์แบบหล่นลงหรือไม่
ตัวอย่างเช่นถ้าฉันมี "foo bar" เป็นข้อมูลและฉันพิมพ์ "foo" ฉันจะได้รับ " foo bar" ในรายการแบบหล่นลงเช่นนี้
ฉันใช้jQuery UI การเติมข้อความอัตโนมัติ Plug-in มีวิธีการเน้นลำดับอักขระการค้นหาในผลลัพธ์แบบหล่นลงหรือไม่
ตัวอย่างเช่นถ้าฉันมี "foo bar" เป็นข้อมูลและฉันพิมพ์ "foo" ฉันจะได้รับ " foo bar" ในรายการแบบหล่นลงเช่นนี้
คำตอบ:
ใช่คุณสามารถทำได้ถ้าคุณลิงเติมข้อความอัตโนมัติ
ในวิดเจ็ตการเติมข้อความอัตโนมัติที่รวมอยู่ใน v1.8rc3 ของ jQuery UI จะมีการสร้างป๊อปอัปของข้อเสนอแนะในฟังก์ชัน _renderMenu ของวิดเจ็ตการเติมข้อความอัตโนมัติ ฟังก์ชั่นนี้กำหนดไว้ดังนี้:
_renderMenu: function( ul, items ) {
var self = this;
$.each( items, function( index, item ) {
self._renderItem( ul, item );
});
},
ฟังก์ชัน _renderItem ถูกกำหนดเช่นนี้:
_renderItem: function( ul, item) {
return $( "<li></li>" )
.data( "item.autocomplete", item )
.append( "<a>" + item.label + "</a>" )
.appendTo( ul );
},
ดังนั้นสิ่งที่คุณต้องทำคือแทนที่ _renderItem fn ด้วยการสร้างของคุณเองที่สร้างผลที่ต้องการ เทคนิคนี้กําหนดฟังก์ชั่นภายในห้องสมุดฉันได้มาเรียนรู้ที่เรียกว่าลิงปะ นี่คือวิธีที่ฉันทำ:
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 );
};
}
$(document).ready(...)
เรียกใช้ฟังก์ชันที่ครั้งหนึ่งใน
ตอนนี้เป็นแฮ็คเพราะ:
มี obj regexp สร้างขึ้นสำหรับทุกรายการที่แสดงในรายการ regexp obj นั้นควรนำมาใช้ใหม่สำหรับทุกรายการ
ไม่มีคลาส css ที่ใช้สำหรับการจัดรูปแบบของส่วนที่เสร็จสมบูรณ์ มันเป็นสไตล์อินไลน์
ซึ่งหมายความว่าหากคุณมีการเติมข้อความอัตโนมัติหลายรายการในหน้าเดียวกันทุกคนจะได้รับการรักษาเหมือนกัน สไตล์ css จะแก้ปัญหานั้น
... แต่มันแสดงให้เห็นถึงเทคนิคหลักและใช้งานได้กับความต้องการขั้นพื้นฐานของคุณ
อัปเดตตัวอย่างการทำงาน: http://output.jsbin.com/qixaxinuhe
ในการรักษาตัวพิมพ์เล็กของสตริงการจับคู่ซึ่งตรงข้ามกับการใช้ตัวพิมพ์ของอักขระให้ใช้บรรทัดนี้:
var t = item.label.replace(re,"<span style='font-weight:bold;color:Blue;'>" +
"$&" +
"</span>");
ในคำอื่น ๆ ที่เริ่มต้นจากรหัสเดิมข้างต้นคุณก็ต้องเปลี่ยนด้วยthis.term
"$&"
แก้ไข
ข้างต้นเปลี่ยนทุกวิดเจ็ตเติมข้อความอัตโนมัติในหน้า หากคุณต้องการเปลี่ยนเพียงครั้งเดียวให้ดูคำถามนี้:
วิธีแก้ไข * เพียงหนึ่งอินสแตนซ์ของการเติมข้อความอัตโนมัติบนหน้าเว็บ
var re = new RegExp(this.term, "i");
โพสต์ยอดเยี่ยม!
ยังใช้งานได้:
$.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 และ @ Cheeso
$().autocomplete()
มีประโยชน์สุด ๆ ขอบคุณ. +1
นี่คือรุ่นไลท์ที่เรียงลำดับตาม "สตริงต้องเริ่มต้นด้วยคำว่า":
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();
นี่เป็นตัวอย่างการทำงานที่สมบูรณ์:
<!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>
หวังว่านี่จะช่วยได้
jQueryUI 1.9.0 เปลี่ยนวิธีการทำงานของ _renderItem
รหัสด้านล่างจะนำการเปลี่ยนแปลงนี้มาพิจารณาด้วยและยังแสดงให้เห็นว่าฉันกำลังทำไฮไลต์การจับคู่โดยใช้ปลั๊กอิน jQuery Autocomplete ของJörn Zaefferer อย่างไร มันจะเน้นคำแต่ละคำทั้งหมดในคำค้นหาโดยรวม
ตั้งแต่เปลี่ยนมาใช้ Knockout และ jqAuto ฉันพบว่านี่เป็นวิธีการจัดแต่งทรงผมที่ง่ายขึ้น
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
สำหรับ for regex ก่อนที่จะทำการประมวลผลใด ๆ ดูEscape string สำหรับใช้ใน Javascript regexซึ่งเป็นหนึ่งในคำตอบมากมายสำหรับวิธีการทำสิ่งนี้
สำหรับวิธีที่ง่ายยิ่งขึ้นลองสิ่งนี้:
$('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)
});
}
นี่คือรูปแบบใหม่ของโซลูชันของ Ted de Koning มันรวมถึง:
$.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);
};
นี่คือรุ่นที่ไม่ต้องใช้นิพจน์ทั่วไปและจับคู่ผลลัพธ์หลายรายการในป้ายกำกับ
$.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 ซึ่งจะรวมถึงการเน้นผลลัพธ์: http://jqueryui.com/demos/autocomplete/#combobox
regex ที่ใช้งานอยู่ที่นั่นยังเกี่ยวข้องกับผลลัพธ์ html
นี่คือรุ่นของฉัน:
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);
};
คุณสามารถใช้รหัส 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;
}
});
และตรรกะ:
$('selector').highlightedautocomplete({...});
มันสร้างเครื่องมือที่กำหนดเองที่สามารถแทนที่ได้_renderItem
โดยไม่ต้องเขียนทับ_renderItem
ต้นแบบปลั๊กอินดั้งเดิม
ในตัวอย่างของฉันยังใช้ฟังก์ชั่นการเรนเดอร์ดั้งเดิมเพื่อลดความซับซ้อนของโค้ด
เป็นสิ่งสำคัญหากคุณต้องการใช้ปลั๊กอินในสถานที่ต่าง ๆ ที่มีมุมมองการเติมข้อความอัตโนมัติที่แตกต่างกันและไม่ต้องการทำลายรหัสของคุณ
หากคุณใช้ปลั๊กอินของบุคคลที่สามแทนที่จะมีตัวเลือกไฮไลต์: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions
(ดูแท็บตัวเลือก)
เพื่อรองรับค่าหลายค่าเพียงเพิ่มฟังก์ชันต่อไปนี้:
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>");