Jak mogę niestandardowo formatować wyniki wtyczki Autocomplete?

Używam jQuery UI Autocomplete plug-in. Czy istnieje sposób na podkreślenie sekwencji znaków wyszukiwania w wynikach rozwijanych?

Na przykład, jeśli mam "foo bar" jako dane i wpiszę "foo", otrzymam "foo bar " w rozwijanym menu, tak:

"Śniadanie" pojawia się po wpisaniu "Bre "z" BRE "o pogrubionym typie i "akfast" o lekkim.

Author: Xufox, 2010-03-13

13 answers

Autouzupełnianie z sugestią na żywo

Tak, możesz, jeśli naprawisz autouzupełnianie.

W widżecie autouzupełniania zawartym w V1. 8rc3 jQuery UI, wyskakujące okienko sugestii jest tworzone w funkcji _rendermenu widżetu autouzupełniania. Funkcja ta jest zdefiniowana następująco:

_renderMenu: function( ul, items ) {
    var self = this;
    $.each( items, function( index, item ) {
        self._renderItem( ul, item );
    });
},

Funkcja _renderItem jest zdefiniowana następująco:

_renderItem: function( ul, item) {
    return $( "<li></li>" )
        .data( "item.autocomplete", item )
        .append( "<a>" + item.label + "</a>" )
        .appendTo( ul );
},

Więc to, co musisz zrobić, to zastąpić ten _renderitem fn własną kreacją, która daje pożądany efekt. To technika, redefiniując wewnętrzną funkcję w bibliotece, doszedłem do nauki nazywa się monkey-patching. Oto jak to zrobiłem:

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

Wywołaj tę funkcję raz w $(document).ready(...) .

Teraz to jest hack, ponieważ:

  • Dla każdego elementu renderowanego na liście jest utworzony regexp obj. To wyrażenie regularne obj powinno być ponownie używane dla wszystkich pozycji.

  • Nie ma klasy css używanej do formatowania ukończonej części. To jest styl inline.
    Oznacza to, że jeśli na tej samej stronie znajduje się wiele autouzupełniania, wszystkie zostaną potraktowane tak samo. Styl css by to rozwiązał.

...ale ilustruje główną technikę i działa na twoje podstawowe wymagania.

alt text

Zaktualizowany przykład roboczy: http://output.jsbin.com/qixaxinuhe


Aby zachować wielkość liter pasujących łańcuchów, w przeciwieństwie do liter wpisywanych znaków, użyj tej linii:

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

Innymi słowy, zaczynając od oryginalnego kodu powyżej, wystarczy zastąpić this.term przez "$&".


EDIT
Powyższy widżet zmienia co widżet autouzupełniania na stronie. Jeśli chcesz zmienić tylko jeden, zobacz to pytanie:
jak łatać* tylko jedną * instancję autouzupełniania na stronie?

 229
Author: Cheeso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-27 14:37:12

To również działa:

       $.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);
        };
Połączenie odpowiedzi @Jörn Zaefferer i @ Cheeso.
 62
Author: Raj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-11 11:29:09

Bardzo pomocne. Dziękuję. +1.

Oto lekka wersja, która sortuje na "String musi zaczynać się od terminu":

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();
 8
Author: orolo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-20 20:43:43

Oto funkcjonalny pełny przykład:

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

Hope this helps

 6
Author: Fabio Nolasco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-24 10:18:23

JQueryUI 1.9.0 zmienia sposób działania _renderItem.

Poniższy kod bierze tę zmianę pod uwagę, a także pokazuje, jak robiłem dopasowanie podświetlenia za pomocą wtyczki jQuery Autocomplete jörna Zaefferera. Podświetli wszystkie poszczególne terminy w ogólnym wyszukiwanym terminie.

Od czasu przejścia do używania Knockout i jqAuto uznałem to za znacznie łatwiejszy sposób stylizacji wyników.

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
Author: 79IT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-04 05:24:36

Dla jeszcze łatwiejszego sposobu, spróbuj tego:

$('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)
});
  }
 3
Author: Aaron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-27 20:57:36

Oto powtórka rozwiązania Teda de Koninga. Obejmuje:

  • Wyszukiwanie niewrażliwe na wielkość liter
  • znajdowanie wielu wystąpień szukanego ciągu
$.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);
};
 3
Author: Pierre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-25 03:22:57

Oto wersja, która nie wymaga żadnych wyrażeń regularnych i pasuje do wielu wyników w etykiecie.

$.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);
};
 2
Author: Ted de Koning,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-08 13:55:32

Spójrz na demo combobox, zawiera podświetlanie wyników: http://jqueryui.com/demos/autocomplete/#combobox

Używane tam wyrażenia regularne dotyczą również wyników html.

 1
Author: Jörn Zaefferer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-04 22:56:21

Oto moja wersja:

  • używa funkcji DOM zamiast RegEx do łamania łańcuchów / inject span tags
  • dotyczy tylko określonego autouzupełniania, nie wszystkich
  • działa z interfejsem użytkownika w wersji 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);
};

Podświetl dopasowany przykład tekstu

 1
Author: Salman A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-28 08:13:45

Możesz użyć następującego kodu:

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

I logika:

$('selector').highlightedautocomplete({...});

Tworzy własny widżet, który może zastąpić _renderItem bez nadpisywania _renderItem oryginalnego prototypu wtyczki.

W moim przykładzie użyłem również oryginalnej funkcji renderującej do jakiegoś uproszczonego kodu

To ważne, jeśli chcesz używać wtyczki w różnych miejscach z różnym widokiem Autouzupełniania i nie chcesz łamać kodu.

 1
Author: E.Monogarov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-16 18:39:20

Jeśli zamiast tego używasz wtyczki 3rd party, ma ona opcję podświetlenia: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions

(patrz zakładka Opcje)

 0
Author: Brian Luft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-12 21:26:14

Aby obsługiwać wiele wartości, po prostu dodaj następującą funkcję:

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>");
 0
Author: ZaieN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-09 03:05:53