Pregunta

Estoy usando el jQuery UI autocompletar plug-in . ¿Hay una manera de destacar secuencia de caracteres en los resultados de búsqueda desplegables?

Por ejemplo, si tengo “foo bar” como datos y escribo "foo" Voy a conseguir “ foo barra” en el desplegable, como esto:

 “Desayuno” después de “Bre” se escribe con “Bre” tener un tipo audaz y “akfast” tener una sola luz.

¿Fue útil?

Solución

 autocompletar con la sugerencia vivo

Sí, puede hacerlo si lo mono-parche de autocompletar.

En el widget de autocompletar incluida en v1.8rc3 de jQuery UI, la ventana emergente de sugerencias se crea en la función _renderMenu del widget de autocompletar. Esta función se define de esta manera:

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

La función _renderItem se define así:

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

Así que lo que hay que hacer es sustituir que _renderItem fn con su propia creación que produce el efecto deseado. Esta técnica, la redefinición de una función interna en una biblioteca, me han enseñado a conocer se llama mono-parches . Así es como lo hice:

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

llamar a esa función una vez en $(document).ready(...).

Ahora, esto es un truco, ya que:

  • hay una expresión regular obj creado para cada elemento dictada en la lista. Eso obj expresión regular debe ser re-utilizado por todos los conceptos.

  • no hay ninguna clase CSS se utiliza para el formato de la pieza terminada. Es un estilo en línea.
    Esto significa que si usted tenía múltiples completa automáticamente en la misma página, todos ellos habían obtener el mismo tratamiento. Un estilo CSS que resolvería.

... pero ilustra la técnica principal, y funciona para sus necesidades básicas.

text alt

actualizado ejemplo de trabajo: http://output.jsbin.com/qixaxinuhe


Para preservar el caso de ambas cadenas son iguales, en lugar de utilizar el caso de los caracteres escritos, utilice esta línea:

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

En otras palabras, a partir del código original anterior, sólo tiene que sustituir this.term con "$&".


Editar
Los cambios anteriores todos widget de autocompletar en la página. Si desea cambiar sólo uno, ver a esta pregunta:
Cómo parchear * sólo uno * instancia de autocompletar en una página?

Otros consejos

Esto también funciona:

       $.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 combinación de Jörn @ @ Zaefferer y respuestas de Cheeso.

Super útil. Gracias. 1.

Esta es una versión ligera que clasifica los "cadena debe comenzar con el término":

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

1.9.0 jQueryUI cambia la forma en _renderItem funciona.

El siguiente código toma en consideración este cambio y también muestra cómo estaba coincidencia más destacado usando el plugin de jQuery Autocompletar de Jörn Zaefferer. Se pondrán de relieve todos los términos individuales en el término de búsqueda global.

Desde que se trasladó a la utilización de Knockout y yo encontramos este jqAuto una manera mucho más fácil de peinar los resultados.

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

Aquí va un ejemplo funcional completo:

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

Espero que esto ayude

de una manera aún más fácil, intente lo siguiente:

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

Esta es una repetición de la solución de Ted de Koning. Incluye:

  • búsqueda que ignore
  • Encontrar muchas ocurrencias de la cadena buscada
$.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);
};

Esta es una versión que no requiere ningún expresiones regulares y coincide con varios resultados en la etiqueta.

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

Tome un vistazo a la demo cuadro combinado, que incluye resaltado resultado: http://jqueryui.com / demos / autocompletar / # combobox

La expresión regular en uso también se ocupa de los resultados del HTML.

Aquí está mi versión:

  • Utiliza funciones DOM en lugar de expresiones regulares para romper las cadenas / inyectar códigos span
  • Sólo el autocompletar especificada se ve afectada, no todos
  • funciona con la versión 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);
};

Selecciona el texto emparejado ejemplo

se puede utilizar código 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;
    }
});

y la lógica:

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

crea widget personalizado que puede anular _renderItem sin sobrescribir _renderItem del prototipo original de plug-in.

en mi ejemplo original, también se utiliza la función de un código simplificar rendir

que es lo importante si desea utilizar el plugin en diferentes lugares con diferentes vistas de autocompletar y no quiere romper su código.

Si en lugar de utilizar el plugin de tercera parte, que tiene una opción más destacado: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions

(véase la ficha Opciones)

Para admitir varios valores, solo basta con añadir la función siguiente:

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>");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top