jquery.tagsinput.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. jQuery Tags Input Plugin 1.2.5
  3. Copyright (c) 2011 XOXCO, Inc
  4. Documentation for this plugin lives here:
  5. http://xoxco.com/clickable/jquery-tags-input
  6. Licensed under the MIT license:
  7. http://www.opensource.org/licenses/mit-license.php
  8. ben@xoxco.com
  9. */
  10. (function($) {
  11. var delimiter = new Array();
  12. var tags_callbacks = new Array();
  13. $.fn.addTag = function(value,options) {
  14. var options = jQuery.extend({focus:false,callback:true},options);
  15. this.each(function() {
  16. id = $(this).attr('id');
  17. var tagslist = $(this).val().split(delimiter[id]);
  18. if (tagslist[0] == '') {
  19. tagslist = new Array();
  20. }
  21. value = jQuery.trim(value);
  22. if (options.unique) {
  23. skipTag = $(tagslist).tagExist(value);
  24. } else {
  25. skipTag = false;
  26. }
  27. if (value !='' && skipTag != true) {
  28. $('<span>').addClass('tag').append(
  29. $('<span>').text(value).append('&nbsp;&nbsp;'),
  30. $('<a>', {
  31. href : '#',
  32. title : 'Removing tag',
  33. text : 'x'
  34. }).click(function () {
  35. return $('#' + id).removeTag(escape(value));
  36. })
  37. ).insertBefore('#' + id + '_addTag');
  38. tagslist.push(value);
  39. $('#'+id+'_tag').val('');
  40. if (options.focus) {
  41. $('#'+id+'_tag').focus();
  42. } else {
  43. $('#'+id+'_tag').blur();
  44. }
  45. if (options.callback && tags_callbacks[id] && tags_callbacks[id]['onAddTag']) {
  46. var f = tags_callbacks[id]['onAddTag'];
  47. f(value);
  48. }
  49. if(tags_callbacks[id] && tags_callbacks[id]['onChange'])
  50. {
  51. var i = tagslist.length;
  52. var f = tags_callbacks[id]['onChange'];
  53. f($(this), tagslist[i]);
  54. }
  55. }
  56. $.fn.tagsInput.updateTagsField(this,tagslist);
  57. });
  58. return false;
  59. };
  60. $.fn.removeTag = function(value) {
  61. value = unescape(value);
  62. this.each(function() {
  63. id = $(this).attr('id');
  64. var old = $(this).val().split(delimiter[id]);
  65. $('#'+id+'_tagsinput .tag').remove();
  66. str = '';
  67. for (i=0; i< old.length; i++) {
  68. if (old[i]!=value) {
  69. str = str + delimiter[id] +old[i];
  70. }
  71. }
  72. $.fn.tagsInput.importTags(this,str);
  73. if (tags_callbacks[id] && tags_callbacks[id]['onRemoveTag']) {
  74. var f = tags_callbacks[id]['onRemoveTag'];
  75. f(value);
  76. }
  77. });
  78. return false;
  79. };
  80. $.fn.tagExist = function(val) {
  81. if (jQuery.inArray(val, $(this)) == -1) {
  82. return false; /* Cannot find value in array */
  83. } else {
  84. return true; /* Value found */
  85. }
  86. };
  87. // clear all existing tags and import new ones from a string
  88. $.fn.importTags = function(str) {
  89. $('#'+id+'_tagsinput .tag').remove();
  90. $.fn.tagsInput.importTags(this,str);
  91. }
  92. $.fn.tagsInput = function(options) {
  93. var settings = jQuery.extend({interactive:true,defaultText:'add a tag',minChars:0,width:'300px',height:'100px','hide':true,'delimiter':',',autocomplete:{selectFirst:false},'unique':true,removeWithBackspace:true},options);
  94. this.each(function() {
  95. if (settings.hide) {
  96. $(this).hide();
  97. }
  98. id = $(this).attr('id')
  99. data = jQuery.extend({
  100. pid:id,
  101. real_input: '#'+id,
  102. holder: '#'+id+'_tagsinput',
  103. input_wrapper: '#'+id+'_addTag',
  104. fake_input: '#'+id+'_tag'
  105. },settings);
  106. delimiter[id] = data.delimiter;
  107. if (settings.onAddTag || settings.onRemoveTag || settings.onChange) {
  108. tags_callbacks[id] = new Array();
  109. tags_callbacks[id]['onAddTag'] = settings.onAddTag;
  110. tags_callbacks[id]['onRemoveTag'] = settings.onRemoveTag;
  111. tags_callbacks[id]['onChange'] = settings.onChange;
  112. }
  113. var markup = '<div id="'+id+'_tagsinput" class="tagsinput"><div id="'+id+'_addTag">';
  114. if (settings.interactive) {
  115. markup = markup + '<input id="'+id+'_tag" value="" data-default="'+settings.defaultText+'" />';
  116. }
  117. markup = markup + '</div><div class="tags_clear"></div></div>';
  118. $(markup).insertAfter(this);
  119. $(data.holder).css('width',settings.width);
  120. $(data.holder).css('height',settings.height);
  121. if ($(data.real_input).val()!='') {
  122. $.fn.tagsInput.importTags($(data.real_input),$(data.real_input).val());
  123. }
  124. if (settings.interactive) {
  125. $(data.fake_input).val($(data.fake_input).attr('data-default'));
  126. $(data.fake_input).css('color','#666666');
  127. $(data.holder).bind('click',data,function(event) {
  128. $(event.data.fake_input).focus();
  129. });
  130. $(data.fake_input).bind('focus',data,function(event) {
  131. if ($(event.data.fake_input).val()==$(event.data.fake_input).attr('data-default')) {
  132. $(event.data.fake_input).val('');
  133. }
  134. $(event.data.fake_input).css('color','#000000');
  135. });
  136. if (settings.autocomplete_url != undefined) {
  137. $(data.fake_input).autocomplete(settings.autocomplete_url,settings.autocomplete).bind('result',data,function(event,data,formatted) {
  138. if (data)
  139. {
  140. $(event.data.real_input).addTag(formatted,{focus:true,unique:(settings.unique)});
  141. }
  142. });
  143. $(data.fake_input).bind('blur',data,function(event) {
  144. if( $('.ac_results').is(':visible') ) return false;
  145. if ( $(event.data.fake_input).val() != $(event.data.fake_input).attr('data-default')) {
  146. if((event.data.minChars <= $(event.data.fake_input).val().length) && (!event.data.maxChars || (event.data.maxChars >= $(event.data.fake_input).val().length)))
  147. $(event.data.real_input).addTag($(event.data.fake_input).val(),{focus:false,unique:(settings.unique)});
  148. }
  149. $(event.data.fake_input).val($(event.data.fake_input).attr('data-default'));
  150. $(event.data.fake_input).css('color','#666666');
  151. return false;
  152. });
  153. } else {
  154. // if a user tabs out of the field, create a new tag
  155. // this is only available if autocomplete is not used.
  156. $(data.fake_input).bind('blur',data,function(event) {
  157. var d = $(this).attr('data-default');
  158. if ($(event.data.fake_input).val()!='' && $(event.data.fake_input).val()!=d) {
  159. if( (event.data.minChars <= $(event.data.fake_input).val().length) && (!event.data.maxChars || (event.data.maxChars >= $(event.data.fake_input).val().length)) )
  160. $(event.data.real_input).addTag($(event.data.fake_input).val(),{focus:true,unique:(settings.unique)});
  161. } else {
  162. $(event.data.fake_input).val($(event.data.fake_input).attr('data-default'));
  163. $(event.data.fake_input).css('color','#666666');
  164. }
  165. return false;
  166. });
  167. }
  168. // if user types a comma, create a new tag
  169. $(data.fake_input).bind('keypress',data,function(event) {
  170. if (event.which==event.data.delimiter.charCodeAt(0) || event.which==13 ) {
  171. if( (event.data.minChars <= $(event.data.fake_input).val().length) && (!event.data.maxChars || (event.data.maxChars >= $(event.data.fake_input).val().length)) )
  172. $(event.data.real_input).addTag($(event.data.fake_input).val(),{focus:true,unique:(settings.unique)});
  173. return false;
  174. }
  175. });
  176. //Delete last tag on backspace
  177. data.removeWithBackspace && $(data.fake_input).bind('keyup', function(event)
  178. {
  179. if(event.keyCode == 8 && $(this).val() == '')
  180. {
  181. var last_tag = $(this).closest('.tagsinput').find('.tag:last').text();
  182. var id = $(this).attr('id').replace(/_tag$/, '');
  183. last_tag = last_tag.replace(/[\s]+x$/, '');
  184. $('#' + id).removeTag(escape(last_tag));
  185. $(this).trigger('focus');
  186. };
  187. });
  188. $(data.fake_input).blur();
  189. } // if settings.interactive
  190. return false;
  191. });
  192. return this;
  193. };
  194. $.fn.tagsInput.updateTagsField = function(obj,tagslist) {
  195. id = $(obj).attr('id');
  196. $(obj).val(tagslist.join(delimiter[id]));
  197. };
  198. $.fn.tagsInput.importTags = function(obj,val) {
  199. $(obj).val('');
  200. id = $(obj).attr('id');
  201. var tags = val.split(delimiter[id]);
  202. for (i=0; i<tags.length; i++) {
  203. $(obj).addTag(tags[i],{focus:false,callback:false});
  204. }
  205. if(tags_callbacks[id] && tags_callbacks[id]['onChange'])
  206. {
  207. var f = tags_callbacks[id]['onChange'];
  208. f(obj, tags[i]);
  209. }
  210. };
  211. })(jQuery);