<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -9,7 +9,6 @@
  */
 
 (function($) {
-
 $.fn.tokenInput = function (url, options) {
     var settings = $.extend({
         url: url,
@@ -25,7 +24,10 @@ $.fn.tokenInput = function (url, options) {
         method: &quot;GET&quot;,
         contentType: &quot;json&quot;,
         queryParam: &quot;q&quot;,
-        onResult: null
+        onResult: null,
+        canCreate: false,
+        editEnabled: false,
+        linkedTagPrefix: null
     }, options);
 
     settings.classes = $.extend({
@@ -34,6 +36,7 @@ $.fn.tokenInput = function (url, options) {
         tokenDelete: &quot;token-input-delete-token&quot;,
         selectedToken: &quot;token-input-selected-token&quot;,
         highlightedToken: &quot;token-input-highlighted-token&quot;,
+        linkedToken: &quot;token-input-linked-token&quot;,
         dropdown: &quot;token-input-dropdown&quot;,
         dropdownItem: &quot;token-input-dropdown-item&quot;,
         dropdownItem2: &quot;token-input-dropdown-item2&quot;,
@@ -43,6 +46,7 @@ $.fn.tokenInput = function (url, options) {
     
     return this.each(function () {
         var list = new $.TokenList(this, settings);
+        this.get_tokenInput = function() { return list };
     });
 };
 
@@ -82,6 +86,9 @@ $.TokenList = function (input, settings) {
 
     // Keep track of the timeout
     var timeout;
+    
+    // Keep track of whether editing is enabled or not
+    var editEnabled = settings.editEnabled;
 
     // Create a new text input an attach keyup events
     var input_box = $(&quot;&lt;input type=\&quot;text\&quot;&gt;&quot;)
@@ -89,6 +96,8 @@ $.TokenList = function (input, settings) {
             outline: &quot;none&quot;,
         })
         .focus(function () {
+            if (!editEnabled) { return false; }
+        
             if (settings.tokenLimit == null || settings.tokenLimit != token_count) {
                 show_dropdown_hint();
             }
@@ -207,29 +216,48 @@ $.TokenList = function (input, settings) {
         .addClass(settings.classes.tokenList)
         .insertAfter(hidden_input)
         .click(function (event) {
-            var li = get_element_from_event(event, &quot;li&quot;);
-            if(li &amp;&amp; li.get(0) != input_token.get(0)) {
-                toggle_select_token(li);
-                return false;
-            } else {
-                input_box.focus();
+            if(editEnabled) {
+                var li = get_element_from_event(event, &quot;li&quot;);
+                if(li &amp;&amp; li.get(0) != input_token.get(0)) {
+                    toggle_select_token(li);
+                    return false;
+                } else {
+                    input_box.focus();
 
-                if(selected_token) {
-                    deselect_token($(selected_token), POSITION.END);
+                    if(selected_token) {
+                        deselect_token($(selected_token), POSITION.END);
+                    }
                 }
             }
+            else {
+                var li = get_element_from_event(event, &quot;li&quot;);
+                if (!li || !settings.linkedTagPrefix ) { return; }
+                
+                window.location.href = settings.linkedTagPrefix
+                    + $.data(li.get(0), &quot;tokeninput&quot;).name;
+            }
         })
         .mouseover(function (event) {
             var li = get_element_from_event(event, &quot;li&quot;);
-            if(li &amp;&amp; selected_token !== this) {
+            if(!li) { return; }
+            
+            if(selected_token !== this) {
                 li.addClass(settings.classes.highlightedToken);
             }
+            if(!editEnabled &amp;&amp; settings.linkedTagPrefix) {
+                li.addClass(settings.classes.linkedToken);
+            }
         })
         .mouseout(function (event) {
             var li = get_element_from_event(event, &quot;li&quot;);
-            if(li &amp;&amp; selected_token !== this) {
+            if(!li) { return; }
+            
+            if(selected_token !== this) {
                 li.removeClass(settings.classes.highlightedToken);
             }
+            if(!editEnabled &amp;&amp; settings.linkedTagPrefix) {
+                li.removeClass(settings.classes.linkedToken);
+            }
         })
         .mousedown(function (event) {
             // Stop user selecting text on tokens
@@ -261,45 +289,10 @@ $.TokenList = function (input, settings) {
 
     // Pre-populate list if items exist
     function init_list () {
-        li_data = settings.prePopulate;
-        if(li_data &amp;&amp; li_data.length) {
-            for(var i in li_data) {
-                var this_token = $(&quot;&lt;li&gt;&lt;p&gt;&quot;+li_data[i].name+&quot;&lt;/p&gt; &lt;/li&gt;&quot;)
-                    .addClass(settings.classes.token)
-                    .insertBefore(input_token);
-
-                $(&quot;&lt;span&gt;x&lt;/span&gt;&quot;)
-                    .addClass(settings.classes.tokenDelete)
-                    .appendTo(this_token)
-                    .click(function () {
-                        delete_token($(this).parent());
-                        return false;
-                    });
-
-                $.data(this_token.get(0), &quot;tokeninput&quot;, {&quot;id&quot;: li_data[i].id, &quot;name&quot;: li_data[i].name});
-
-                // Clear input box and make sure it keeps focus
-                input_box
-                    .val(&quot;&quot;)
-                    .focus();
-
-                // Don't show the help dropdown, they've got the idea
-                hide_dropdown();
-
-                // Save this token id
-                var id_string = li_data[i].id + &quot;,&quot;
-                hidden_input.val(hidden_input.val() + id_string);
-            }
-        } else if(settings.prePopulateFromInput) {
-        	var values = hidden_input.val().split(',');
-        	hidden_input.val('');
-        	
-        	$.each(values, function() {
-        		var value = $.trim(this);
-        		if(value.length &gt; 0) add_token(value, value);
-        	});
-        } else {
-        	hidden_input.val('');
+        if(settings.prePopulate) {
+            $.each(settings.prePopulate, function(i, item) {
+                create_token(item);
+            });
         }
     }
 
@@ -350,8 +343,14 @@ $.TokenList = function (input, settings) {
     }
 
     // Add a token to the token list based on user input
-    function add_token (id, name) {
-        var this_token = insert_token(id, name);
+    function add_token (item) {
+        var li_data = $.data(item.get(0), &quot;tokeninput&quot;);
+        
+        create_token(li_data);
+    }
+    
+    function create_token (li_data) {
+        var this_token = insert_token(li_data.id, li_data.name);
 
         // Clear input box and make sure it keeps focus
         input_box
@@ -364,13 +363,37 @@ $.TokenList = function (input, settings) {
         // Save this token id
         var id_string = id + &quot;,&quot;
         hidden_input.val(hidden_input.val() + id_string);
-        
+
         token_count++;
         
         if(settings.tokenLimit != null &amp;&amp; settings.tokenLimit &gt;= token_count) {
             input_box.hide();
             hide_dropdown();
         }
+
+        $(hidden_input).trigger('tokenadd', {
+            update: update_token,
+            remove: delete_token,
+            data: li_data,
+            token: this_token.get(0)
+        });
+    }
+    
+    function update_token (item, data) {
+        var old_data = $.data(item, &quot;tokeninput&quot;);
+        var new_data = {
+            id: data.id == undefined ? old_data.id : data.id,
+            name: data.name == undefined ? old_data.name : data.name
+        };
+        
+        $.data(item, &quot;tokeninput&quot;, data);
+        
+        var old_id_string = old_data.id + &quot;,&quot;;
+        var new_id_string = new_data.id + &quot;,&quot;;
+        
+        hidden_input.val(
+            hidden_input.val().replace(old_id_string, new_id_string)
+        );
     }
     
     function create_new_token () {
@@ -450,6 +473,11 @@ $.TokenList = function (input, settings) {
                 .val(&quot;&quot;)
                 .focus();
         }
+
+        $(hidden_input).trigger('tokendelete', {
+            add: create_token,
+            data: token_data
+        });
     }
 
     // Hide and clear the results dropdown
@@ -457,6 +485,22 @@ $.TokenList = function (input, settings) {
         dropdown.hide().empty();
         selected_dropdown_item = null;
     }
+    
+    function hide_inputbox () {
+        input_box.hide().empty();
+    }
+    
+    function hide_tagdelete () {
+        $('.' + settings.classes.tokenDelete, token_list).hide();
+    }
+    
+    function show_tagdelete () {
+        $('.' + settings.classes.tokenDelete, token_list).show();
+    }
+    
+    function show_inputbox () {
+        input_box.show();
+    }
 
     function show_dropdown_searching () {
     	if(settings.searchingText.length &gt; 0) {
@@ -479,7 +523,7 @@ $.TokenList = function (input, settings) {
 
     // Populate the results dropdown with some results
     function populate_dropdown (query, results) {
-        if(results.length) {
+        if(results.length || settings.canCreate) {
             dropdown.empty();
             var dropdown_ul = $(&quot;&lt;ul&gt;&quot;)
                 .appendTo(dropdown)
@@ -497,8 +541,20 @@ $.TokenList = function (input, settings) {
                 })
                 .hide();
 
+            // Check for duplicates
+            var resultAdded = new Array();
+            $(&quot;.&quot; + settings.classes.token, token_list)
+                .each(function(i, val) {
+                    var data = $.data(val, &quot;tokeninput&quot;);
+                    resultAdded[data.name] = 1;
+                }
+            );
+            
+            // Save the first li for selecting
+            var firstLi;
+
             for(var i in results) {
-                if (results.hasOwnProperty(i)) {
+                if (results.hasOwnProperty(i) &amp;&amp; !resultAdded[results[i].name]) {
                     var this_li = $(&quot;&lt;li&gt;&quot;+highlight_term(results[i].name, query)+&quot;&lt;/li&gt;&quot;)
                                       .appendTo(dropdown_ul);
 
@@ -509,12 +565,34 @@ $.TokenList = function (input, settings) {
                     }
 
                     if(i == 0) {
-                        select_dropdown_item(this_li);
+                        firstLi = this_li;
                     }
-
+                    
+                    resultAdded[results[i].name] = 1;
                     $.data(this_li.get(0), &quot;tokeninput&quot;, {&quot;id&quot;: results[i].id, &quot;name&quot;: results[i].name});
                 }
             }
+            
+            // If canCreate option enabled, show &quot;Create 'token-name'&quot;
+            if(settings.canCreate &amp;&amp; !resultAdded[query]) {
+                var li = $(&quot;&lt;li&gt;Create '&quot; + query + &quot;'&lt;/li&gt;&quot;)
+                            .appendTo(dropdown_ul);
+                // li.addClass(results.length%2 ? settings.classes.dropdownItem : settings.classes.dropdownItem2);
+                if(results.length % 2) {
+                    li.addClass(settings.classes.dropdownItem);
+                } else {
+                    li.addClass(settings.classes.dropdownItem2);
+                }
+                
+                if(results.length == 0) {
+                    firstLi = li;
+                }
+                
+                $.data(li.get(0), &quot;tokeninput&quot;, { &quot;id&quot;: &quot;+&quot; + query, &quot;name&quot;: query });
+            }
+            if(firstLi) {
+                select_dropdown_item(firstLi);
+            }
 
             dropdown.show();
             dropdown_ul.show();
@@ -587,10 +665,23 @@ $.TokenList = function (input, settings) {
             };
             
             if(settings.method == &quot;POST&quot;) {
-			    $.post(settings.url, settings.queryParam + &quot;=&quot; + query, callback, settings.contentType);
-		    } else {
-		        $.get(settings.url + queryStringDelimiter + settings.queryParam + &quot;=&quot; + query, {}, callback, settings.contentType);
-		    }
+                $.post(settings.url, settings.queryParam + &quot;=&quot; + query, callback, settings.contentType);
+            } else {
+                $.get(settings.url + queryStringDelimiter + settings.queryParam + &quot;=&quot; + query, {}, callback, settings.contentType);
+            }
+        }
+    }
+    
+    this.editable = function (enable) {
+        editEnabled = enable === undefined ? true : enable;
+        if (editEnabled) {
+            show_inputbox();
+            show_tagdelete();
+        }
+        else {
+            hide_dropdown();
+            hide_inputbox();
+            hide_tagdelete();
         }
     }
 };
@@ -626,4 +717,4 @@ $.TokenList.Cache = function (options) {
     };
 };
 
-})(jQuery);
\ No newline at end of file
+})(jQuery);</diff>
      <filename>src/jquery.tokeninput.js</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>28b26083cd8afdf0a94803df983f173e42db2d61</id>
    </parent>
    <parent>
      <id>0c5304574cb455209a95202b1d756e8c6825fc7a</id>
    </parent>
  </parents>
  <author>
    <name>Felix Clack</name>
    <email>felixclack@gmail.com</email>
  </author>
  <url>http://github.com/kid80/jQuery-Tokenizing-Autocomplete-Plugin/commit/56b10b81fdf1388a62527e472d2483166f210466</url>
  <id>56b10b81fdf1388a62527e472d2483166f210466</id>
  <committed-date>2009-09-28T09:05:09-07:00</committed-date>
  <authored-date>2009-09-28T09:05:09-07:00</authored-date>
  <message>Merge nickspacek changes.</message>
  <tree>2cd8e2ebcb5e00a9d8a7fd9d8a97d9434da4c921</tree>
  <committer>
    <name>Felix Clack</name>
    <email>felixclack@gmail.com</email>
  </committer>
</commit>
