7

I'm using the autocomplete plugin by Andrew Whitaker, also referenced in this question: jquery autocomplete @mention

This doesn't work if I use a contenteditable div instead of a textarea. Here's my code:

<div id="MyText" contenteditable="true"></div>​

$("#MyText").bind("keydown", function (event) {
        if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) {
            event.preventDefault();
        }
    }).autocomplete({
        minLength: 0,
        source: function (request, response) {
            var term = request.term,
                results = [];
            if (term.indexOf("@") >= 0) {
                term = extractLast(request.term);
                if (term.length > 0) {
                    results = $.ui.autocomplete.filter(tags, term);
                } else {
                    results = [startTyping];
                }
            }
            response(results);
        },
        focus: function () {
            return false;
        },
        select: function (event, ui) {
            if (ui.item.value !== startTyping) {
                var terms = this.value.split(' ');
                terms.pop();
                terms.push("@" + ui.item.value + "</span>");
                this.value = terms.join(" ");
            }
            return false;
        }
    }).data("autocomplete")._renderItem = function (ul, item) {
        if (item.label != startTyping) {
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a><div><img src='" + item.icon + "'/></div><div>" + item.label + "</div></div></a>")
                .appendTo(ul);
        } else {
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a>" + item.label + "</a>")
                .appendTo(ul);
        }
    };

Any thoughts?

Community
  • 1
  • 1
Prabhu
  • 12,995
  • 33
  • 127
  • 210
  • 1
    have you check this [question](http://stackoverflow.com/questions/4836562/is-it-posible-to-have-jquery-ui-autocomplete-on-a-contenteditable-div-and-datepi) ? – yosafatade Nov 10 '12 at 18:39
  • Thanks, I checked it. It solves half my problem. The issue is that when I select the item from the list, it doesn't get added to the div. – Prabhu Nov 10 '12 at 19:27
  • As of 2019, the answer seem outdated, with the browser console logging a `TypeError`. [jQuery](https://jqueryui.com/autocomplete/) has a better, modern example – Brad Solomon Jul 12 '19 at 16:38

2 Answers2

18

The main difference between an input/textarea and a contenteditable div is that you access the latter content with the .html() method (instead of the .value or .val() method.

Here is the autocomplete code:

$("#MyText")
    .bind("keydown", function (event) {
        if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) {
            event.preventDefault();
        }
    })
    .autocomplete({
        minLength: 0,
        source: function (request, response) {
            var term = request.term,
                results = [];
            if (term.indexOf("@") >= 0) {
                term = extractLast(request.term);
                if (term.length > 0) {
                    results = $.ui.autocomplete.filter(tags, term);
                } else {
                    results = [startTyping];
                }
            }
            response(results);
        },
        focus: function () {
            return false;
        },
        select: function (event, ui) {
            if (ui.item.value !== startTyping) {
                var value = $(this).html();
                var terms = split(value);
                terms.pop();
                terms.push(ui.item.value);
                $(this).html(terms.join("@"));
                placeCaretAtEnd(this);
            }
            return false;
        }
    })
    .data("autocomplete")._renderItem = function (ul, item) {
        if (item.label != startTyping) {
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a><div>" + item.label + "</div></div></a>")
                .appendTo(ul);
        } else {
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a>" + item.label + "</a>")
                .appendTo(ul);
        }
    }
;

EDIT(2): Here is the link to the jsfiddle

marty
  • 4,005
  • 22
  • 19
  • Thanks for your answer. However, the problem I'm having (and also with your jsfiddle) is that the cursor goes to the starting position after selecting the item. Any idea how to have the cursor appear at the end of the selected item? – Prabhu Feb 25 '13 at 02:45
  • @Prabhu, ok, with the help of Tim Down's answer in http://stackoverflow.com/questions/4233265/contenteditable-set-caret-at-the-end-of-the-text-cross-browser/4238971#4238971 I've been able to move the cursor to the end. See updated jsfiddle in my answer. – marty Feb 25 '13 at 16:28
  • Very cool. There's one more issue with the jsFiddle though, hoping you can help me with it. When you select multiple items, the previously selected item loses the first character (the @ sign). Thanks a lot for your help. – Prabhu Feb 27 '13 at 00:24
  • very helpful example!! :) – Yagnesh bhalala Jan 11 '18 at 07:48
3

Above example was not working See this http://jsfiddle.net/ipsjolly/jYJjJ/29/

select: function (event, ui) {

            var value = $(this).html();
            var terms = split(value);
            terms.pop();
            terms.push(ui.item.value);
            $(this).html(terms+", ");
            placeCaretAtEnd(this);

        return false;
    }
Code Spy
  • 9,626
  • 4
  • 66
  • 46