Domanda

Sto usando il Plug-in di completamento automatico dell'interfaccia utente jQuery.Esiste un modo per evidenziare la sequenza di caratteri di ricerca nei risultati a discesa?

Ad esempio, se ho "foo bar" come dati e digito "foo" otterrò "pippo bar” nel menu a discesa, in questo modo:

“Breakfast” appears after “Bre” is typed with “Bre” having a bold type and “akfast” having a light one.

È stato utile?

Soluzione

 completamento automatico con il suggerimento dal vivo

Sì, è possibile se si scimmia-patch completamento automatico.

Nel widget completamento automatico incluso nel v1.8rc3 di jQuery UI, il popup di suggerimenti viene creato nella funzione _renderMenu del widget di completamento automatico. Questa funzione è definita in questo modo:

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

La funzione _renderItem è definita in questo modo:

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

Quindi quello che dovete fare è sostituire che _renderItem fn con la propria creazione che produce l'effetto desiderato. Questa tecnica, ridefinendo una funzione interna in una libreria, sono venuto ad imparare è chiamato scimmia-patching . Ecco come ho fatto:

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

chiamare tale funzione, una volta in $(document).ready(...).

Ora, questo è un hack, perché:

  • c'è un obj regexp creato per ogni elemento reso in lista. Che regexp obj dovrebbe essere riutilizzate per tutti gli elementi.

  • non c'è classe CSS utilizzata per la formattazione della parte completata. Si tratta di uno stile in linea.
    Questo significa che se si ha più autocompletes sulla stessa pagina, avevano tutte ottenere lo stesso trattamento. Uno stile css risolverebbe questo.

... ma illustra la tecnica principale, e funziona per le vostre esigenze di base.

alt text

esempio funzionante aggiornamento: http://output.jsbin.com/qixaxinuhe


Per preservare il caso delle corde partita, anziché utilizzare il caso dei caratteri digitati, utilizzare questa linea:

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

In altre parole, a partire dal codice originale di cui sopra, basta sostituire this.term con "$&".


Modifica
Le modifiche di cui sopra tutti widget di completamento automatico nella pagina. Se si desidera modificare una sola, questa domanda:
Come applicare la patch * solo * istanza di completamento automatico in una pagina?

Altri suggerimenti

questo funziona anche:

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

una combinazione di @ Jörn Zaefferer e @ risposte di Cheeso.

super disponibile. Grazie. 1.

Ecco una versione leggera che ordina su "String deve iniziare con il termine":

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 cambia come _renderItem funziona.

Il codice di seguito prende questo cambiamento in considerazione e mostra come stavo facendo corrispondenza evidenziazione utilizzando plugin per jQuery Autocomplete di Jörn Zaefferer anche. Si metterà in evidenza tutti i singoli termini nel termine di ricerca generale.

Dopo essersi trasferito a utilizzare Knockout e jqAuto Ho trovato un modo molto più semplice di styling dei risultati.

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

Qui si va, un esempio completo funzionale:

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

Spero che questo aiuti

un modo ancora più semplice, provate questo:

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

Ecco una rivisitazione della soluzione di Ted de Koning.Include :

  • Ricerca senza distinzione tra maiuscole e minuscole
  • Trovare molte occorrenze della stringa cercata
$.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);
};

Ecco una versione che non richiede alcuna espressioni regolari e corrisponde a più risultati nell'etichetta.

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

Date un'occhiata alla casella combinata demo, include risultato evidenziazione: http://jqueryui.com / demo / completamento automatico / # combobox

L'espressione regolare in uso si occupa anche lì con risultati HTML.

Qui è la mia versione:

  • Utilizza funzioni DOM invece di RegEx per rompere le stringhe / iniettare tag span
  • il completamento automatico specificato viene influenzato solo, non tutti
  • funziona con la versione 1.9.x UI
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);
};

Evidenziare il testo abbinato esempio

è possibile utilizzare il codice 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;
    }
});

e la logica:

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

crea widget personalizzato che può ignorare _renderItem senza sovrascrivere _renderItem del prototipo plug-in originale.

nel mio esempio anche usato originale funzione per un certo codice semplificare il rendering

è importante se si desidera utilizzare plug-in in luoghi diversi con differenti vista del completamento automatico e non si vuole rompere il vostro codice.

Se si utilizza invece il plugin 3rd party, che ha un'opzione highlight: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions

(vedi la scheda Opzioni)

Per supportare più valori, semplicemente aggiungere seguente funzione:

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>");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top