1

https://stackoverflow.com/a/7222592/2332251など、いくつかの質問を見てきました

私はまだ持っているコードとそれを調整するのに苦労しています。

現時点では、入力を開始したときにユーザー名を検索するために、次の方法が完全に機能します。

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

searchusers.php の関数は、データベースからユーザー名を出力します。

私が言ったように、私は他の @mention ソリューションをうまく機能させるのに苦労しています。他のソリューションをコピーして詳細を交換しようとしましたが、何もうまくいかないようです。

そう...

  1. 最初に「@」記号を入力したときにのみ読み込まれるようにするには、現在のオートコンプリート スクリプトに何をする必要がありますか?
  2. 投稿で複数の @メンションを使用できるようにしたい
  3. (オプション)オートコンプリートがユーザー名を提案し、リストからユーザー名を選択すると、投稿に表示され、ユーザー名の前に@記号が追加されたままになります。たとえば、「こんにちは@ジョン、@記号はまだあなたのユーザー名」

さらに情報が必要な場合は、コメントしてください。さらに情報を提供します:)

編集それを機能させるための構文が本当にわかりません。たとえば、上に投稿した回答例を使用すると、次のようになりました (ただし、機能しません)。

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 $("<li>")
        .data("item.autocomplete", item)
        .append("<a>" + item.label + "&nbsp;<span class='count'>(" + item.count + ")</span></a>")
        .appendTo(ul);
};
});

searchusers.php、#appendedInputButton、およびその他の特定の情報はどこに挿入すればよいですか? これが理にかなっていることを願っています。

4

2 に答える 2

4

私のコメントに基づいて回答を作成します。

まず、要件のリストを確認しましょう。

  • @記号で始まるオートコンプリートのユーザー名
  • ユーザー名の先頭に@記号を追加
  • テキスト内の複数の @メンション
  • テキスト内の任意の @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 $("<li>")
            .data("ui-autocomplete-item", item)
            .append("<a>" + item.label + "&nbsp;<span class='count'>(" + item.count + ")</span></a>")
            .appendTo(ul);
    };
});
于 2013-06-11T16:06:41.183 に答える
0

コメントを追加できないので、これを回答として追加します。

あなたが提供したコードスニペットを試してみましたが、うまくいきました。私が抱えていた唯一の問題は、言及を編集しているときでした. メンションの途中から編集することにしたところ、オートコンプリートが表示され、アイテムの選択に成功しました。のみ - 前の言及の残りは削除せず、カーソル位置の前の文字のみを削除しました。

だから私は何か余分なものを追加しました:

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

残り物をカバーするために、選択機能を少し変更しました。現在、次の " " 出現を検索し、その前のすべての長さを置換値に追加します。

お役に立てれば :)

于 2016-06-23T16:18:00.577 に答える