내가 사용하고 jQuery를 UI 자동 완성 플러그인을 . 드롭 다운 결과에서 검색 문자 순서를 강조 표시하는 방법이 있습니까?
예를 들어, 데이터로 "foo bar"가 있고 "foo"를 입력 하면 다음과 같이 드롭 다운에 " foo bar"가 표시됩니다.
내가 사용하고 jQuery를 UI 자동 완성 플러그인을 . 드롭 다운 결과에서 검색 문자 순서를 강조 표시하는 방법이 있습니까?
예를 들어, 데이터로 "foo bar"가 있고 "foo"를 입력 하면 다음과 같이 드롭 다운에 " foo bar"가 표시됩니다.
답변:
예, 원숭이 패치 자동 완성 기능을 사용할 수 있습니다.
jQuery UI v1.8rc3에 포함 된 자동 완성 위젯에서 제안 팝업은 자동 완성 위젯의 _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가 생성됩니다. 해당 정규 표현식 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의 작동 방식을 변경합니다.
아래 코드는 이러한 변경 사항을 고려하고 Jörn Zaefferer의 jQuery Autocomplete 플러그인을 사용하여 하이라이트 일치를 수행 한 방법을 보여줍니다. 전체 검색어에서 모든 개별 용어를 강조 표시합니다.
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
처리하기 전에 정규식 을 이스케이프 처리하는 일부 논리를 사용해야합니다. 이 작업을 수행하는 방법에 대한 많은 답변 중 하나로 Javascript 정규식에 사용되는 이스케이프 문자열을 참조하십시오 .
더 쉬운 방법으로 다음을 시도하십시오.
$('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);
};
콤보 박스 데모를 살펴보면 결과 강조 표시가 포함되어 있습니다. http://jqueryui.com/demos/autocomplete/#combobox
거기에 사용되는 정규식은 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);
};
다음 코드를 사용할 수 있습니다.
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
(옵션 탭 참조)