Как я могу настроить параметры подключаемого модуля Autocomplete?

Im, используя jQuery UI Autocomplete plug-in. Есть ли способ выделить последовательность символов поиска в раскрывающихся результатах?

Например, если у меня есть "foo bar" в качестве данных, и я набираю "foo" Ill, чтобы получить " foo bar" в раскрывающемся списке, например:

Ответ 1

Автозаполнение с живым предложением

Да, вы можете, если у вас есть автозаполнение обезьяны-патча.

В виджетах автозаполнения, включенном в v1.8rc3 пользовательского интерфейса jQuery, всплывающее окно предложений создается в функции _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(...).

Теперь это взломать, потому что:

  • существует regexp obj, созданный для каждого элемента, отображаемого в списке. Этот regexp obj должен быть повторно использован для всех элементов.

  • для форматирования завершенной части нет класса css. Это встроенный стиль.
    Это означает, что если на одной странице было несколько автозаполнений, все они получат одинаковое обращение. Стиль css решит это.

... но он иллюстрирует основную технику и работает для ваших основных требований.

alt text

обновленный рабочий пример: http://output.jsbin.com/qixaxinuhe


Чтобы сохранить случай строк соответствия, в отличие от использования введенных символов, используйте эту строку:

var t = item.label.replace(re,"<span style='font-weight:bold;color:Blue;'>" + 
          "$&" + 
          "</span>");

Другими словами, начиная с исходного кода выше, вам просто нужно заменить this.term на "$&".


ИЗМЕНИТЬ
Вышеизложенное изменяет каждый виджет автозаполнения на странице. Если вы хотите изменить только один, см. Этот вопрос:
Как исправить * только один экземпляр Autocomplete на странице?

Ответ 2

это также работает:

       $.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.

Ответ 3

Супер полезно. Спасибо. +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();

Ответ 4

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();
});

Ответ 5

Вот он, полный функциональный пример:

<!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>

Надеюсь, что это поможет

Ответ 6

для еще более простого способа, попробуйте следующее:

$('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)
});
  }

Ответ 7

Здесь вы найдете решение Теда де Конинга. Он включает в себя:

  • Нечувствительный к регистру поиск
  • Поиск многих вхождений искомой строки
$.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);
};

Ответ 8

Вот версия, которая не требует каких-либо регулярных выражений и соответствует нескольким результатам в метке.

$.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);
};

Ответ 9

Взгляните на демонстрацию combobox, она включает выделение результатов: http://jqueryui.com/demos/autocomplete/#combobox

В используемом регулярном выражении также рассматриваются результаты html.

Ответ 10

Вот моя версия:

  • Использование функций DOM вместо RegEx для прерывания строк/ввода тегов span
  • Возникает только указанный автозаполнение, а не все
  • Работает с пользовательским интерфейсом версии 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);
};

Выделить пример с сопоставленным текстом

Ответ 11

вы можете использовать следующий код:

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 исходного прототипа плагина.

в моем примере также использовалась оригинальная функция рендеринга для некоторого упрощенного кода

Это важно, если вы хотите использовать плагин в разных местах с различным представлением автозаполнения и не хотите разорвать свой код.

Ответ 13

Чтобы поддерживать несколько значений, просто добавьте следующую функцию:

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>");