Je recherche une implémentation Javascript à complétion automatique incluant les éléments suivants:
@
et démarre la saisie semi-automatique lorsqu'il est tapéJe pense que cela ressemble à ce que fait Twitter lorsque vous insérez un tweet, mais je ne parviens pas à trouver une implémentation agréable et réutilisable.
Une solution avec jQuery serait parfaite.
Merci.
Je ne pouvais trouver aucune solution correspondant parfaitement à mes besoins. Je me suis donc retrouvé avec ce qui suit:
J'utilise l'événement jQuery keypress()
pour vérifier si l'utilisateur appuie sur le caractère @
.
Si c'est le cas, une boîte de dialogue modale est affichée à l'aide de l'interface utilisateur jQuery. Cette boîte de dialogue contient un champ de texte autocomplete (de nombreuses options peuvent être utilisées ici, mais je recommande jQuery Tokeninput ).
Lorsque l'utilisateur sélectionne une option dans la boîte de dialogue, une balise est ajoutée au champ de texte et la boîte de dialogue est fermée.
Ce n'est pas la solution la plus élégante, mais cela fonctionne et cela ne nécessite pas de pression supplémentaire sur les touches par rapport à ma conception d'origine.
Modifier
Donc, en gros, nous avons notre grande zone de texte où l’utilisateur peut saisir du texte. Il devrait être capable de "taguer" un utilisateur (cela signifie simplement d'insérer #<userid>
dans le texte). J'attache à l'événement jQuery keyup et détecte le caractère @
à l'aide de (e.which == 64)
pour afficher une modale avec un champ de texte permettant de sélectionner les utilisateurs à baliser.
La solution réside simplement dans ce dialogue modal avec une zone de texte jQuery Tokeninput . Au fur et à mesure que l'utilisateur tape ici, la liste des utilisateurs est chargée via AJAX. Voir les exemples sur le site Web pour savoir comment l'utiliser correctement. Lorsque l'utilisateur ferme la boîte de dialogue, j'insère les identifiants sélectionnés dans la grande zone de texte.
Je suis sûr que votre problème est résolu depuis longtemps, mais jquery-textcomplete semble faire l'affaire.
Avez-vous essayé cela
GITHUB: https://github.com/podio/jquery-mentions-input
DEMO/CONFIG: http://podio.github.io/jquery-mentions-input/
C'est assez simple à mettre en œuvre.
Essaye ça:
(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/ Ce lien vous aidera
J'ai créé un paquet Meteor à cet effet. Le modèle de données de Meteor permet une recherche multi-règles rapide avec des listes de rendu personnalisées. Si vous n'utilisez pas Meteor pour votre application Web, vous ne trouverez malheureusement rien d'aussi génial pour l'auto-complétion.
Complétion automatique des utilisateurs avec @
, où les utilisateurs en ligne sont affichés en vert:
Dans la même ligne, compléter automatiquement quelque chose avec des icônes de métadonnées et d'amorçage:
Fourchez, tirez et améliorez:
Récemment, j'ai dû faire face à ce problème et c'est comme ça que j'ai cloué ...
Cela fonctionne dans tous les derniers navigateurs. n'ont pas testé chez les anciens
Voici Bac de travail
Un autre plugin offrant des fonctionnalités similaires:
Vous pouvez l'utiliser avec des déclencheurs personnalisés ou sans aucun déclencheur. Fonctionne avec les champs de saisie, textareas et contenteditables. Et jQuery n'est pas une dépendance.
Cette petite extension semble être la plus proche au moins dans la présentation de ce qui a été demandé. Comme il est petit, il peut être facilement compris et modifié. http://lookapanda.github.io/jquery-hashtags/