jQuery Tag Editor

A plugin for editing tags on an element. by Chris Coleman [email protected] license : free to use non-commercial purposes, just let me know so I can see it in the wild. contact me for commercial use and support of this code and/or any previous version of this code in the save history. twitter.com/kneebreaker http://www.linkedin.com/profile/view?id=37980744 this is a live working draft, so it will upgrade here every time I come play with it. I will have a website up soon and a repository and formal documentation soon

by 1eddy87

HTML

<h1>jQuery Tag Editor</h1>
<p>by Chris Coleman</p>
<p>Usage: Type in the box, hit enter or ',' to add tag to the list. Click the button to show the hidden values</p>

<ul class="tagList">
  <li class="tag">baz</li>
</ul>

<input type="button" id="showHidden" value="Show Hidden Field Values" />
<input type="button" id="getVals" value="Show values via plugin method" />

<p>Displayed tags are added both by the data object and an existing list item</p>
<code>
    //creates a basic tag list with a hidden input field with a specific id
    var tagList = $('ul.tagList').tagList({ id: 'yourModelPropertyId' });
    //creates a basic tag list with existing data
    var tagList = $('ul.tagList').tagList({ data: ['foo','bar'], id: 'yourModelPropertyId'});
    //you can also do the above with the following HTML if you don't want to use the data property
    &lt;ul class="tagList"&gt;
        &lt;li class="tag"&gt;foo&lt;/li&gt;
        &lt;li class="tag"&gt;bar&lt;/li&gt;
    &lt;/ul&gt;
</code>

<p>To Do</p>
<ul>
  <li>handle more keys, preferably by regex instead of ascii range http://stackoverflow.com/questions/2257070/detect-numbers-or-letters-with-jquery-javascript
  </li>
  <li>add animations and custom animation support</li>
  <li>add sort functionality</li>
  <li>jquery ui themeroller support</li>
  <li>let user specify the template structure for certain elements</li>
  <li>actually use templates</li>
  <li>unit testing</li>
  <li>clean code a bit, I see some no-nos in here, and it is still ugly from coding before planning</li>
</ul>

CSS

ul.tagList,
ol.tagList,
p {
  margin: 10px 0px;
}

.tagList li {
  display: inline-block;
  margin: 0px 4px 0px 0px;
  padding: 4px 6px;
  vertical-align: middle;
  background-color: #ccf;
  border-color: #ccc;
}

.tagList li.hidden {
  display: none;
}

a.delete {
  background: url("http://www.nightfallstudios.com/download.png") no-repeat scroll center 0 transparent;
  display: inline-block;
  height: 10px;
  margin: 0 0 0 6px;
  text-indent: -999px;
  vertical-align: middle;
  width: 10px;
}

.tagList .activeInput input {
  width: 6px;
}

code {
  background-color: #F9F9FF;
  border: 2px dotted #CCCCFF;
  display: block;
  padding: 10px;
  white-space: pre-wrap;
}

JavaScript

//see left-side info tab for license

//thanks to:
//plugin boilerplate from Stefan Gabos
//http://stefangabos.ro/jquery/jquery-plugin-boilerplate-revisited/

(function($) {
  $.tagList = function(element, options) {
    var defaults = {
      //function for adding a tag
      add: addTag,
      //function for removing a tag
      remove: removeTag,
      //callback events
      afterAdd: function() {},
      afterRemove: function() {},
      beforeAdd: function() {},
      beforeRemove: function() {},
      //remove image attributes
      removeImgText: 'remove',
      removeImgAttrs: {
        'href': '#',
        'class': 'delete',
        'alt': 'remove'
      },
      //array of values
      data: [],
      id: 'changeMe',
      formatValues: updateHidden
    };

    var plugin = this;
    plugin.settings = {};

    var $element = $(element), //current jquery element that was passed to the plugin
      $activeItem = $('<li class="activeInput">').appendTo($element),
      $activeSpan = $('<span class="activeValue"></span>').appendTo($activeItem), //wtf ie? seriously?
      $activeInput = $('<input type="text" />').appendTo($activeItem),
      $valueLi = $('<li class="hidden">').appendTo($element),
      $valueField = $('<input type="hidden">').appendTo($valueLi);

    //template for the delete button on the list items - img totally stolen from fb
    var $deleteImg = function() {
      return $('<a>')
        .text(plugin.settings.removeImgText)
        .attr(plugin.settings.removeImgAttrs);
    };

    //template for list items containing tags in tag list
    var $tagTemplate = function(value) {
      return $('<li>').text(value).attr({
        'class': 'tag'
      });
    };

    plugin.init = function() {
      plugin.settings = $.extend({}, defaults, options);

      $valueField.prop('id', plugin.settings.id);

      //handle existing items
      $('li.tag', $element).each(function() {
        var clone = $(this).clone();
        $(this).remove();
       ...