textcomplete mention atwho javascript jquery html ajax twitter

javascript - atwho - jquery mention autocomplete



Autocompletar estilo Twitter en textarea (9)

Creé un paquete Meteor para este propósito. El modelo de datos de Meteor permite una búsqueda rápida de múltiples reglas con listas renderizadas personalizadas. Si no está usando Meteor para su aplicación web, (creo) desafortunadamente no encontrará nada tan asombroso para la autocompletación.

Autocompletar usuarios con @ , donde los usuarios en línea se muestran en verde:

En la misma línea, autocompletar otra cosa con metadatos e iconos de arranque:

Bifurcar, tirar y mejorar:

https://github.com/mizzao/meteor-autocomplete

Estoy buscando una implementación de autocompletado de Javascript que incluya lo siguiente:

  • Se puede usar en un área de texto HTML
  • Permite escribir texto regular sin invocar autocompletar
  • Detecta el carácter @ y comienza a autocompletarse cuando se escribe
  • Carga la lista de opciones a través de AJAX

Creo que esto es similar a lo que Twitter está haciendo al etiquetar en un tweet, pero no puedo encontrar una implementación agradable y reutilizable.
Una solución con jQuery sería perfecta.

Gracias.



Estoy seguro de que su problema ha sido solucionado hace tiempo, pero jquery-textcomplete parece que haría el trabajo.



No pude encontrar ninguna solución que coincidiera perfectamente con mis requisitos, así que terminé con lo siguiente:

Uso el evento jQuery keypress() para verificar que el usuario presione el carácter @ .
Si este es el caso, se muestra un cuadro de diálogo modal usando jQuery UI. Este cuadro de diálogo contiene un campo de texto de autocompletar (se pueden usar muchas opciones aquí, pero recomiendo jQuery Tokeninput )
Cuando el usuario selecciona una opción en el cuadro de diálogo, se agrega una etiqueta al campo de texto y se cierra el cuadro de diálogo.

Esta no es la solución más elegante, pero funciona y no requiere presionar teclas adicionales en comparación con mi diseño original.

Editar
Entonces, básicamente, tenemos nuestro cuadro de texto grande donde el usuario puede ingresar texto. Debería poder "etiquetar" a un usuario (esto solo significa insertar #<userid> en el texto). Me apego al evento jQuery keyup y detecto el carácter @ usando (e.which == 64) para mostrar un modal con un campo de texto para seleccionar a los usuarios a etiquetar.

La carne de la solución es simplemente este diálogo modal con un cuadro de texto jQuery Tokeninput . A medida que el usuario escribe aquí, la lista de usuarios se carga a través de AJAX. Vea los ejemplos en el sitio web para saber cómo usarlo correctamente. Cuando el usuario cierra el diálogo, inserto los ID seleccionados en el cuadro de texto grande.


Otra gran biblioteca que resuelve este problema At.js

Source

Demo


Prueba esto:

(function($){ $.widget("ui.tagging", { // default options options: { source: [], maxItemDisplay: 3, autosize: true, animateResize: false, animateDuration: 50 }, _create: function() { var self = this; this.activeSearch = false; this.searchTerm = ""; this.beginFrom = 0; this.wrapper = $("<div>") .addClass("ui-tagging-wrap"); this.highlight = $("<div></div>"); this.highlightWrapper = $("<span></span>") .addClass("ui-corner-all"); this.highlightContainer = $("<div>") .addClass("ui-tagging-highlight") .append(this.highlight); this.meta = $("<input>") .attr("type", "hidden") .addClass("ui-tagging-meta"); this.container = $("<div></div>") .width(this.element.width()) .insertBefore(this.element) .addClass("ui-tagging") .append( this.highlightContainer, this.element.wrap(this.wrapper).parent(), this.meta ); var initialHeight = this.element.height(); this.element.height(this.element.css(''lineHeight'')); this.element.keypress(function(e) { // activate on @ if (e.which == 64 && !self.activeSearch) { self.activeSearch = true; self.beginFrom = e.target.selectionStart + 1; } // deactivate on space if (e.which == 32 && self.activeSearch) { self.activeSearch = false; } }).bind("expand keyup keydown change", function(e) { var cur = self.highlight.find("span"), val = self.element.val(), prevHeight = self.element.height(), rowHeight = self.element.css(''lineHeight''), newHeight = 0; cur.each(function(i) { var s = $(this); val = val.replace(s.text(), $("<div>").append(s).html()); }); self.highlight.html(val); newHeight = self.element.height(rowHeight)[0].scrollHeight; self.element.height(prevHeight); if (newHeight < initialHeight) { newHeight = initialHeight; } if (!$.browser.mozilla) { if (self.element.css(''paddingBottom'') || self.element.css(''paddingTop'')) { var padInt = parseInt(self.element.css(''paddingBottom'').replace(''px'', '''')) + parseInt(self.element.css(''paddingTop'').replace(''px'', '''')); newHeight -= padInt; } } self.options.animateResize ? self.element.stop(true, true).animate({ height: newHeight }, self.options.animateDuration) : self.element.height(newHeight); var widget = self.element.autocomplete("widget"); widget.position({ my: "left top", at: "left bottom", of: self.container }).width(self.container.width()-4); }).autocomplete({ minLength: 0, delay: 0, maxDisplay: this.options.maxItemDisplay, open: function(event, ui) { var widget = $(this).autocomplete("widget"); widget.position({ my: "left top", at: "left bottom", of: self.container }).width(self.container.width()-4); }, source: function(request, response) { if (self.activeSearch) { self.searchTerm = request.term.substring(self.beginFrom); if (request.term.substring(self.beginFrom - 1, self.beginFrom) != "@") { self.activeSearch = false; self.beginFrom = 0; self.searchTerm = ""; } if (self.searchTerm != "") { if ($.type(self.options.source) == "function") { self.options.source(request, response); } else { var re = new RegExp("^" + escape(self.searchTerm) + ".+", "i"); var matches = []; $.each(self.options.source, function() { if (this.label.match(re)) { matches.push(this); } }); response(matches); } } } }, focus: function() { // prevent value inserted on focus return false; }, select: function(event, ui) { self.activeSearch = false; //console.log("@"+searchTerm, ui.item.label); this.value = this.value.replace("@" + self.searchTerm, ui.item.label) + '' ''; self.highlight.html( self.highlight.html() .replace("@" + self.searchTerm, $("<div>").append( self.highlightWrapper .text(ui.item.label) .clone() ).html()+'' '') ); self.meta.val((self.meta.val() + " @[" + ui.item.value + ":]").trim()); return false; } }); } });

body, html { font-family: "lucida grande",tahoma,verdana,arial,sans-serif; } .ui-tagging { position: relative; border: 1px solid #B4BBCD; height: auto; } .ui-tagging .ui-tagging-highlight { position: absolute; padding: 5px; overflow: hidden; } .ui-tagging .ui-tagging-highlight div { color: transparent; font-size: 13px; line-height: 18px; white-space: pre-wrap; } .ui-tagging .ui-tagging-wrap { position: relative; padding: 5px; overflow: hidden; zoom: 1; border: 0; } .ui-tagging div > span { background-color: #D8DFEA; font-weight: normal !important; } .ui-tagging textarea { display: block; font-family: "lucida grande",tahoma,verdana,arial,sans-serif; background: transparent; border-width: 0; font-size: 13px; height: 18px; outline: none; resize: none; vertical-align: top; width: 100%; line-height: 18px; overflow: hidden; } .ui-autocomplete { font-size: 13px; background-color: white; border: 1px solid black; margin-bottom: -5px; width: 0; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <textarea></textarea>

http://jsfiddle.net/mekwall/mcWnL/52/ Este enlace te ayudará


Recientemente tuve que enfrentar este problema y esta es la forma en que clavé ...

  1. Obtenga el índice de cadena en la posición del cursor en el área de texto usando selectionStart
  2. cortar la cadena del índice 0 a la posición del cursor
  3. Insértelo en un lapso (ya que el tramo tiene múltiples casillas de borde)
  4. Obtenga las dimensiones del cuadro de borde usando element.getClientRects () relativo al puerto de vista. (aquí está la referencia de MDN )
  5. Calcule la parte superior e izquierda y alimente al menú desplegable

Esto funciona en todos los navegadores más recientes. no he probado en los viejos

Aquí está la papelera de trabajo


THIS debería funcionar Con respecto a @ iniciar la búsqueda, simplemente agregue (dinámicamente o no) el símbolo al comienzo de cada posible término de búsqueda.