jQuery UI Tagging

by Marcus Ekwall

HTML

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/themes/base/jquery-ui.css">
<textarea></textarea>

CSS

body, html {
    font-family: "lucida grande",tahoma,verdana,arial,sans-serif;
}

.ui-tagging {
    position: relative;
    border: 1px solid #B4BBCD;
    height: auto;
}

.ui-tagging .ui-tagging-highlight {
    position: absolute;
    padding: 5px;
    overflow: hidden;
}
.ui-tagging .ui-tagging-highlight div {
    color: transparent;
    font-size: 13px;
    line-height: 18px;
    white-space: pre-wrap;
}

.ui-tagging .ui-tagging-wrap {
    position: relative;
    padding: 5px;
    overflow: hidden;
    zoom: 1;
    border: 0;
}

.ui-tagging div > span {
    background-color: #D8DFEA;
    font-weight: normal !important;
}

.ui-tagging textarea {
    display: block;
    font-family: "lucida grande",tahoma,verdana,arial,sans-serif;
    background: transparent;
    border-width: 0;
    font-size: 13px;
    height: 18px;
    outline: none;
    resize: none;
    vertical-align: top;
    width: 100%;
    line-height: 18px;
    overflow: hidden;
}

.ui-autocomplete {
    font-size: 13px;
    background-color: white;
    border: 1px solid black;
    margin-bottom: -5px;
    width: 0;
}

JavaScript

(function($){

    $.widget("ui.tagging", {
        // default options
        options: {
            source: [],
            maxItemDisplay: 3,
            autosize: true,
            animateResize: false,
            animateDuration: 50
        },
        _create: function() {
            var self = this;
            
            this.activeSearch = false;
            this.searchTerm = "";
            this.beginFrom = 0;

            this.wrapper = $("<div>")
                .addClass("ui-tagging-wrap");
            
            this.highlight = $("<div></div>");
            
            this.highlightWrapper = $("<span></span>")
                .addClass("ui-corner-all");

            this.highlightContainer = $("<div>")
                .addClass("ui-tagging-highlight")
                .append(this.highlight);

            this.meta = $("<input>")
                .attr("type", "hidden")
                .addClass("ui-tagging-meta");

            this.container = $("<div></div>")
                .width(this.element.width())
                .insertBefore(this.element)
                .addClass("ui-tagging")
                .append(
                    this.highlightContainer, 
                    this.element.wrap(this.wrapper).parent(), 
                    this.meta
                );
            
            var initialHeight = this.element.height();
            
            this.element.height(this.element.css('lineHeight'));
            
            this.element.keypress(function(e) {
                // activate on @
                if (e.which == 64 && !self.activeSearch) {
                    self.activeSearch = true;
                    self.beginFrom = e.target.selectionStart + 1;
                }
                // deactivate on space
                if (e.which == 32 && self.activeSearch) {
                    self.activeSearch = false;
                }
            }).bind("expand keyup keydown change", function(e) {
                var cur =...