多个jQuery UI在一个页面上提到自动完成

时间:2014-01-17 13:38:44

标签: javascript jquery autocomplete

我无法获得多次提及自动完成工作@mention - 类似于FB等。

我已经查看了SO并找到了一些关于做基本提及自动完成的好例子,并且基于我的一个,即: https://stackoverflow.com/a/17048788/2981412

然而,我需要让它在一页上的MULTIPLE(....无限)textareas中工作,而不仅仅是一个(上面的答案做得好)。

当我将它添加到多个(使用类选择器而不是ID)时,其他的不能正常显示。 请参阅我的基本示例,其中包含虚拟数据:

http://jsfiddle.net/yv8mn/3/

最顶级的textarea工作正常,但其他人显示一个空的下拉式自动完成菜单。

有什么想法吗?

JS ......

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) {
    var data = {
        tags: [
            {username: 'john', count: 1}, {username: 'michael', count: 1} 
        ]
    };
            callback(data); 


}

$(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 {
                                username: el.username,
                                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.username + this.value.substr(pos);
                setCaretPosition(this, prependStr.length + ui.item.username.length + 1);
            }    
            return false;
        }
    }).data("ui-autocomplete")._renderItem = function(ul, item) {
        return $("<li>")
            .data("ui-autocomplete-item", item)
            .append("<a>" + item.username+" ("+ item.count+")</a>")
            .appendTo(ul);
    };
});

2 个答案:

答案 0 :(得分:0)

下拉菜单实际上不是空的,列表项非常非常薄。尝试单击一个,您将看到信息已插入文本区域。

所以看起来一切正常,除了造型因某种原因。

答案 1 :(得分:0)

我找到了解决问题的方法。

它首先涉及从问题中删除我的代码的以下部分:

.data("ui-autocomplete")._renderItem = function(ul, item) {
        return $("<li>")
            .data("ui-autocomplete-item", item)
            .append("<a>" + item.username+" ("+ item.count+")</a>")
            .appendTo(ul);
    }

并用这两个解决方案的两个替换它们(都修复了它):

$.each($( "ui-autocomplete" ), function(index, item) {
            $(item).data("ui-autocomplete")._renderItem = function (ul, item) {
                return $("<li>")
            .data("ui-autocomplete-item", item)
            .append("<a>" + item.username+" ("+ item.count+")</a>")
            .appendTo(ul);
            };
        });

    $.ui.autocomplete.prototype._renderItem = function (ul, item) {
                    return $("<li>")
            .data("ui-autocomplete-item", item)
            .append("<a>" + item.username+" ("+ item.count+")</a>")
            .appendTo(ul);
                };
}

然后会产生以下代码(如果使用初始解决方案):

    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) {
    var data = {
        tags: [
            {username: 'john', count: 1}, {username: 'michael', count: 1} 
        ]
    };
            callback(data); 


}

$(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 {
                                username: el.username,
                                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.username + this.value.substr(pos);
                setCaretPosition(this, prependStr.length + ui.item.username.length + 1);
            }    
            return false;
        }
    });
$.each($( "ui-autocomplete" ), function(index, item) {
            $(item).data("ui-autocomplete")._renderItem = function (ul, item) {
                return $("<li>")
            .data("ui-autocomplete-item", item)
            .append("<a>" + item.username+" ("+ item.count+")</a>")
            .appendTo(ul);
            };
        });
});