将 jQuery 自动完成数据附加到文本区域内容而不是覆盖它

Append jQuery autocomplete data to textarea content instead of overwriting it

我正在尝试让 @ 其他人在我的 rails 应用程序中运行,就像 Whosebug:

我快完成这个功能了,但是我遇到了问题,jQuery自动完成数据替换了我的textarea内容,而不是追加。

Coffeescript:

find_at_sign = ->
  if $("#tags").val().split('').pop() == "@"
    id = $("#tags").data("article-id")
    $("#tags").autocomplete
      source:  '/articles/' + id + '/autocomplete.json'
      minLength: 1

$ ->
  $(document).on("input", "#tags",
  -> find_at_sign())

文章负责人:

  def autocomplete
    @articles = Article.find_by(id: params[:article_id])
    @commentor_names = @articles.comments.map(&:name).uniq
    respond_to do |format|
      format.html
      format.json {
        render json: @commentor_names
      }
    end
  end

form_html.erb:

 <div class="form-group ui-widget">
    <div class="col-sm-5">
      <%= f.text_area :content, rows: 5, placeholder: '说点什么...', 
          class: 'form-control', id: "tags", 'data-article-id': @article.id.to_s %>
    </div>
  </div>

我尝试使用 append 方法,但不起作用:

$("#tags").append(${this).autocomplete
  source:  '/articles/' + id + '/autocomplete.json'
  minLength: 1)

感谢任何帮助!

您可以执行以下两项操作之一:

  1. 您可以简单地 replace 带有您想要的内容的 @ 符号,但这可能会给您带来麻烦。

  2. 您可以获取光标位置并在光标后添加内容,这可能需要一些工作。

这是一个例子:

 function (tid) {

        node=$('#'+tid)[0];

        try{
        //--- Wrap selected text or insert at curser.
        var oldText         = node.value || node.textContent;
        var newText;
        var iTargetStart    = node.selectionStart;
        var iTargetEnd      = node.selectionEnd;

        if (iTargetStart == iTargetEnd)
            newText         = left+right;
        else
            newText         = left + oldText.slice (iTargetStart, iTargetEnd) + right;

        //console.log (newText);
        newText             = oldText.slice (0, iTargetStart) + newText + oldText.slice (iTargetEnd);
        node.value          = newText;
        //-- After using spelling corrector, this gets buggered, hence the multiple sets.
        node.textContent    = newText;
        //-- Have to reset selection, since we repasted the text.
        node.selectionStart = iTargetStart + left.length;
        node.selectionEnd   = iTargetEnd   + left.length;
            node.focus ();
....

see full code

这是我基于 this example 的半心半意的尝试。重要位如下:

  • 取消内置的 focus 事件试图覆盖文本框内的值
  • 取消内置 select 事件并将其配置为将所选 @name 添加到文本框内而不是覆盖它
  • 提供自定义 source 函数,从文本框中提取最后一个 @name 并查找该名称和 returns 匹配的名称

var namelist = [
  "Adam",
  "Adrian",
  "Andrew",
  "Charles",
  "Daniel",
  "David",
  "Evan",
  "Henry",
  "Ian",
  "Jack",
  "James",
  "John",
  "Joseph",
  "Justin",
  "Kevin",
  "Michael",
  "Parker",
  "Robert",
  "Thomas",
  "William"
];
$(function() {
  $("#message").autocomplete({
    source: function(request, response) {
      var match = request.term.match(/@(\w*)$/);
      var names = match ? $.ui.autocomplete.filter(namelist, match[1]) : [];
      response(names)
    },
    focus: function(event) {
      event.preventDefault();
    },
    select: function(event, ui) {
      event.preventDefault();
      this.value = this.value.replace(/@(\w*)$/, "@" + ui.item.value)
    }
  })
});
@import url("https://code.jquery.com/ui/1.11.4/themes/ui-darkness/jquery-ui.min.css");

body {
  font: smaller sans-serif;
}
textarea {
  box-sizing: border-box;
  width: 100%;
  height: 5em;
}
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>


<p>Enter some text or @name</p>
<textarea id="message"></textarea>

我正在为此使用 jquery 插件:http://yuku-t.com/jquery-textcomplete/