如何自定义格式化自动完成插件结果?
我正在使用jQuery UI自动完成插件 。 有没有办法在下拉式结果中突出显示search字符序列?
例如,如果我有“富酒吧”作为数据,我键入“富”我会在下拉菜单中获得“ 富酒吧”,如下所示:
是的,你可以如果你猴子补丁自动完成。
在jQuery UI v1.8rc3中包含的自动填充小部件中,build议的popup窗口在自动填充小部件的_renderMenu函数中创build。 这个function是这样定义的:
_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 fnreplace为你自己的创build,产生所需的效果。 这种技术,重新定义了图书馆的内部function,我来学习叫做猴子修补 。 以下是我如何做到的:
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(...)
调用该函数一次。
现在,这是一个黑客,因为:
-
有一个正则expression式obj为列表中呈现的每个项目创build。 该正则expression式obj应该被重新用于所有项目。
-
没有用于格式化完成的部分的CSS类。 这是一种内联风格。
这意味着如果您在同一页面上有多个自动填充,他们都会得到相同的处理。 一个CSS风格可以解决这个问题。
…但它说明了主要技术,它适用于您的基本要求。
更新的工作示例: http : //output.jsbin.com/qixaxinuhe
为了保留匹配string的大小写,与使用input字符的大小写相反,请使用以下行:
var t = item.label.replace(re,"<span style='font-weight:bold;color:Blue;'>" + "$&" + "</span>");
换句话说,从上面的原始代码开始,你只需要用"$&"
代替this.term
。
编辑
以上更改页面上的每个自动完成小部件。 如果您只想更改一个,请参阅以下问题:
如何在页面上修补*一个自动完成的实例?
这也适用:
$.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örnZaefferer和@Ceseso的反应相结合。
超级有用。 谢谢。 +1。
这里是一个轻的版本,sorting“string必须以术语开始”:
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改变_renderItem的工作方式。
下面的代码将这个变化考虑在内,同时也展示了我如何使用JörnZaefferer的jQuery自动完成插件进行高亮匹配。 它将突出显示整个search字词中的所有单词。
由于移动到使用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(); });
这是一个function完整的例子:
<!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>
希望这可以帮助
为了更简单的方法,试试这个:
$('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解决scheme的重头戏。 这包括 :
- 不区分大小写的search
- 查找search到的string的很多事件
$.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); };
这是一个不需要任何正则expression式的版本,并且匹配标签中的多个结果。
$.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
这里使用的正则expression式也处理html结果。
这是我的版本:
- 使用DOM函数而不是RegEx来破坏string/注入span标签
- 只有指定的自动完成function受到影响,而不是全部
- 适用于UI版本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); };
突出显示匹配的文本示
你可以使用下面的代码:
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({...});
它创build自定义小部件,可以覆盖_renderItem
而不覆盖原始插件原型的_renderItem
。
在我的例子中也使用了原始的渲染function来简化一些代码
如果你想在不同的地方使用不同的自动完成视图的插件,而不想破坏你的代码,这是很重要的。
如果您使用第三方插件,它有一个突出显示选项: http : //docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions
(请参阅选项选项卡)
要支持多个值,只需添加以下function:
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>");