获取jQuery ui自动完成function仅适用于@mentions

我看了几个问题,比如https://stackoverflow.com/a/7222592/2332251

我仍然无法将其与我的代码进行协调。

目前,当我开始输入时,以下内容完美地用于搜索用户名。

$(function() { $("#appendedInputButton").autocomplete({ minLength: 2, source: "searchusers.php" }); }); 

searchusers.php中的函数输出数据库中的用户名。

正如我所说,我无法让其他@mention解决方案为我工作。 我试过复制其他解决方案并交换我的细节,但似乎没有任何效果。

所以…

  1. 如果我最初键入“@”符号,我需要对当前的自动完成脚本做什么才能加载它?
  2. 我真的希望能够在我的post中拥有多个@mentions
  3. (可选)当自动完成建议用户名时,当我从列表中选择用户名时,我希望它出现在我的post中,@ mysmbol仍然附加在用户名的前面,例如“hello @john,@符号仍然附加到你的用户名”

如果您需要更多信息,请发表评论,我会提供更多:)

编辑我真的不确定使它工作的语法。 例如,使用我上面发布的示例答案,我提出了(但它不起作用):

 function split(val) { return val.split(/@\s*/); } function extractLast(term) { return split(term).pop(); } function getTags(term, callback) { $.ajax({ url: "searchusers.php", data: { filter: term, pagesize: 5 }, type: "POST", success: callback, jsonp: "jsonp", dataType: "jsonp" }); } $(document).ready(function() { $("#appendedInputButton") // don't navigate away from the field on tab when selecting an item .bind("keydown", function(event) { if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) { event.preventDefault(); } }).autocomplete({ source: function(request, response) { if (request.term.indexOf("@") >= 0) { $("#loading").show(); getTags(extractLast(request.term), function(data) { response($.map(data.tags, function(el) { return { value: el.name, count: el.count } })); $("#loading").hide(); }); } }, focus: function() { // prevent value inserted on focus return false; }, select: function(event, ui) { var terms = split(this.value); // remove the current input terms.pop(); // add the selected item terms.push(ui.item.value); // add placeholder to get the comma-and-space at the end terms.push(""); this.value = terms.join(""); return false; } }).data("autocomplete")._renderItem = function(ul, item) { return $("
  • ") .data("item.autocomplete", item) .append("" + item.label + " (" + item.count + ")") .appendTo(ul); }; });
  • 我在哪里插入searchusers.php,#attachInputButton和其他具体信息? 我希望这是有道理的。

    我会根据我的评论形成答案。

    首先让我们回顾一下要求列表:

    • 自动完成用户名以@符号开头
    • 使用@符号添加用户名
    • 文本中的多个@mentions
    • 在文本的任何地方编辑任何@mention

    要实现最后一个要求,我需要一些我在stackoverflow上找到的魔术函数:

    另外,为了检测文本中某处的用户名,我们需要为用户名定义一些约束。 我假设它只能有字母和数字,并用\w+模式进行测试。

    您可以在这里找到的实时演示http://jsfiddle.net/AU92X/6/它总是返回2行而不进行过滤只是为了演示行为。 在下面的列表中,我已经从问题中放入了原始的getTags函数,因为它对我来说很合适。 虽然我不知道searchusers.php是如何工作的。

     function getCaretPosition (elem) { // Initialize var iCaretPos = 0; // IE Support if (document.selection) { // Set focus on the element elem.focus (); // To get cursor position, get empty selection range var oSel = document.selection.createRange (); // Move selection start to 0 position oSel.moveStart ('character', -elem.value.length); // The caret position is selection length iCaretPos = oSel.text.length; } // Firefox support else if (elem.selectionStart || elem.selectionStart == '0') iCaretPos = elem.selectionStart; // Return results return (iCaretPos); } function setCaretPosition(elem, caretPos) { if(elem != null) { if(elem.createTextRange) { var range = elem.createTextRange(); range.move('character', caretPos); range.select(); } else { if(elem.selectionStart) { elem.focus(); elem.setSelectionRange(caretPos, caretPos); } else elem.focus(); } } } function getTags(term, callback) { $.ajax({ url: "searchusers.php", data: { filter: term, pagesize: 5 }, type: "POST", success: callback, jsonp: "jsonp", dataType: "jsonp" }); } $(document).ready(function() { $("#appendedInputButton").autocomplete({ source: function(request, response) { var term = request.term; var pos = getCaretPosition(this.element.get(0)); var substr = term.substring(0, pos); var lastIndex = substr.lastIndexOf('@'); if (lastIndex >= 0){ var username = substr.substr(lastIndex + 1); if (username.length && (/^\w+$/g).test(username)){ getTags(username, function(data) { response($.map(data.tags, function(el) { return { value: el.name, count: el.count } })); }); return; } } response({}); }, focus: function() { // prevent value inserted on focus return false; }, select: function(event, ui) { var pos = getCaretPosition(this); var substr = this.value.substring(0, pos); var lastIndex = substr.lastIndexOf('@'); if (lastIndex >= 0){ var prependStr = this.value.substring(0, lastIndex); this.value = prependStr + '@' + ui.item.value + this.value.substr(pos); setCaretPosition(this, prependStr.length + ui.item.value.length + 1); } return false; } }).data("ui-autocomplete")._renderItem = function(ul, item) { return $("
  • ") .data("ui-autocomplete-item", item) .append("" + item.label + " (" + item.count + ")") .appendTo(ul); }; });
  • 我无法添加评论,所以我只想将其添加为答案。

    我尝试了你提供的代码片段,效果很好。 我唯一的问题是在编辑提及时。 我决定从提及中间编辑,自动完成显示,我成功选择了一个项目。 只 – 它没有删除前面提到的其余部分,只删除了光标位置之前的字母。

    所以我添加了额外的东西:

     select: function(event, ui) { var pos = comments.init.getCaretPosition(this); var substr = this.value.substring(0, pos); var lastIndex = substr.lastIndexOf('@'); var afterPosString = this.value.substring(pos, this.value.length); var leftovers = afterPosString.indexOf(' '); if (leftovers == -1) leftovers = afterPosString.length; if (lastIndex >= 0){ var prependStr = this.value.substring(0, lastIndex); this.value = prependStr + '@' + ui.item.value + this.value.substr(pos + leftovers); comments.init.setCaretPosition(this, prependStr.length + ui.item.value.length + 1); } return false; } 

    我稍微更改了选择function以覆盖剩菜。 现在,它正在搜索下一个“”事件,并将之前的所有内容的长度添加到替换值。

    希望这可以帮助 :)