PageRenderTime 27ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/public/assets/theme/assets/global/plugins/jquery-tags-input/jquery.tagsinput.js

https://gitlab.com/techniconline/kmc
JavaScript | 358 lines | 280 code | 52 blank | 26 comment | 81 complexity | d5c962be4a267ed9b310e7dee6d1e393 MD5 | raw file
  1. /*
  2. jQuery Tags Input Plugin 1.3.3
  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.doAutosize = function (o) {
  14. var minWidth = $(this).data('minwidth'),
  15. maxWidth = $(this).data('maxwidth'),
  16. val = '',
  17. input = $(this),
  18. testSubject = $('#' + $(this).data('tester_id'));
  19. if (val === (val = input.val())) {
  20. return;
  21. }
  22. // Enter new content into testSubject
  23. var escaped = val.replace(/&/g, '&amp;').replace(/\s/g, ' ').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  24. testSubject.html(escaped);
  25. // Calculate new width + whether to change
  26. var testerWidth = testSubject.width(),
  27. newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
  28. currentWidth = input.width(),
  29. isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
  30. || (newWidth > minWidth && newWidth < maxWidth);
  31. // Animate width
  32. if (isValidWidthChange) {
  33. input.width(newWidth);
  34. }
  35. };
  36. $.fn.resetAutosize = function (options) {
  37. // alert(JSON.stringify(options));
  38. var minWidth = $(this).data('minwidth') || options.minInputWidth || $(this).width(),
  39. maxWidth = $(this).data('maxwidth') || options.maxInputWidth || ($(this).closest('.tagsinput').width() - options.inputPadding),
  40. val = '',
  41. input = $(this),
  42. testSubject = $('<tester/>').css({
  43. position: 'absolute',
  44. top: -9999,
  45. left: -9999,
  46. width: 'auto',
  47. fontSize: input.css('fontSize'),
  48. fontFamily: input.css('fontFamily'),
  49. fontWeight: input.css('fontWeight'),
  50. letterSpacing: input.css('letterSpacing'),
  51. whiteSpace: 'nowrap'
  52. }),
  53. testerId = $(this).attr('id') + '_autosize_tester';
  54. if (!$('#' + testerId).length > 0) {
  55. testSubject.attr('id', testerId);
  56. testSubject.appendTo('body');
  57. }
  58. input.data('minwidth', minWidth);
  59. input.data('maxwidth', maxWidth);
  60. input.data('tester_id', testerId);
  61. input.css('width', minWidth);
  62. };
  63. $.fn.addTag = function (value, options) {
  64. options = jQuery.extend({focus: false, callback: true}, options);
  65. this.each(function () {
  66. var id = $(this).attr('id');
  67. var tagslist = $(this).val().split(delimiter[id]);
  68. if (tagslist[0] == '') {
  69. tagslist = new Array();
  70. }
  71. value = jQuery.trim(value);
  72. if (options.unique) {
  73. var skipTag = $(this).tagExist(value);
  74. if (skipTag == true) {
  75. //Marks fake input as not_valid to let styling it
  76. $('#' + id + '_tag').addClass('not_valid');
  77. }
  78. } else {
  79. var skipTag = false;
  80. }
  81. if (value != '' && skipTag != true) {
  82. $('<span>').addClass('tag').append(
  83. $('<span>').text(value).append('&nbsp;&nbsp;'),
  84. $('<a>', {
  85. href: '#',
  86. title: 'Removing tag',
  87. text: 'x'
  88. }).click(function () {
  89. return $('#' + id).removeTag(escape(value));
  90. })
  91. ).insertBefore('#' + id + '_addTag');
  92. tagslist.push(value);
  93. $('#' + id + '_tag').val('');
  94. if (options.focus) {
  95. $('#' + id + '_tag').focus();
  96. } else {
  97. $('#' + id + '_tag').blur();
  98. }
  99. $.fn.tagsInput.updateTagsField(this, tagslist);
  100. if (options.callback && tags_callbacks[id] && tags_callbacks[id]['onAddTag']) {
  101. var f = tags_callbacks[id]['onAddTag'];
  102. f.call(this, value);
  103. }
  104. if (tags_callbacks[id] && tags_callbacks[id]['onChange']) {
  105. var i = tagslist.length;
  106. var f = tags_callbacks[id]['onChange'];
  107. f.call(this, $(this), tagslist[i - 1]);
  108. }
  109. }
  110. });
  111. return false;
  112. };
  113. $.fn.removeTag = function (value) {
  114. value = unescape(value);
  115. this.each(function () {
  116. var id = $(this).attr('id');
  117. var old = $(this).val().split(delimiter[id]);
  118. $('#' + id + '_tagsinput .tag').remove();
  119. str = '';
  120. for (i = 0; i < old.length; i++) {
  121. if (old[i] != value) {
  122. str = str + delimiter[id] + old[i];
  123. }
  124. }
  125. $.fn.tagsInput.importTags(this, str);
  126. if (tags_callbacks[id] && tags_callbacks[id]['onRemoveTag']) {
  127. var f = tags_callbacks[id]['onRemoveTag'];
  128. f.call(this, value);
  129. }
  130. });
  131. return false;
  132. };
  133. $.fn.tagExist = function (val) {
  134. var id = $(this).attr('id');
  135. var tagslist = $(this).val().split(delimiter[id]);
  136. return (jQuery.inArray(val, tagslist) >= 0); //true when tag exists, false when not
  137. };
  138. // clear all existing tags and import new ones from a string
  139. $.fn.importTags = function (str) {
  140. id = $(this).attr('id');
  141. $('#' + id + '_tagsinput .tag').remove();
  142. $.fn.tagsInput.importTags(this, str);
  143. }
  144. $.fn.tagsInput = function (options) {
  145. var settings = jQuery.extend({
  146. interactive: true,
  147. defaultText: 'add a tag',
  148. minChars: 0,
  149. width: '300px',
  150. height: '100px',
  151. autocomplete: {selectFirst: false},
  152. 'hide': true,
  153. 'delimiter': ',',
  154. 'unique': true,
  155. removeWithBackspace: true,
  156. placeholderColor: '#666666',
  157. autosize: true,
  158. comfortZone: 20,
  159. inputPadding: 6 * 2
  160. }, options);
  161. this.each(function () {
  162. if (settings.hide) {
  163. $(this).hide();
  164. }
  165. var id = $(this).attr('id');
  166. if (!id || delimiter[$(this).attr('id')]) {
  167. id = $(this).attr('id', 'tags' + new Date().getTime()).attr('id');
  168. }
  169. var data = jQuery.extend({
  170. pid: id,
  171. real_input: '#' + id,
  172. holder: '#' + id + '_tagsinput',
  173. input_wrapper: '#' + id + '_addTag',
  174. fake_input: '#' + id + '_tag'
  175. }, settings);
  176. delimiter[id] = data.delimiter;
  177. if (settings.onAddTag || settings.onRemoveTag || settings.onChange) {
  178. tags_callbacks[id] = new Array();
  179. tags_callbacks[id]['onAddTag'] = settings.onAddTag;
  180. tags_callbacks[id]['onRemoveTag'] = settings.onRemoveTag;
  181. tags_callbacks[id]['onChange'] = settings.onChange;
  182. }
  183. var markup = '<div id="' + id + '_tagsinput" class="tagsinput"><div id="' + id + '_addTag">';
  184. if (settings.interactive) {
  185. markup = markup + '<input id="' + id + '_tag" value="" data-default="' + settings.defaultText + '" />';
  186. }
  187. markup = markup + '</div><div class="tags_clear"></div></div>';
  188. $(markup).insertAfter(this);
  189. $(data.holder).css('width', settings.width);
  190. $(data.holder).css('min-height', settings.height);
  191. $(data.holder).css('height', '100%');
  192. if ($(data.real_input).val() != '') {
  193. $.fn.tagsInput.importTags($(data.real_input), $(data.real_input).val());
  194. }
  195. if (settings.interactive) {
  196. $(data.fake_input).val($(data.fake_input).attr('data-default'));
  197. $(data.fake_input).css('color', settings.placeholderColor);
  198. $(data.fake_input).resetAutosize(settings);
  199. $(data.holder).bind('click', data, function (event) {
  200. $(event.data.fake_input).focus();
  201. });
  202. $(data.fake_input).bind('focus', data, function (event) {
  203. if ($(event.data.fake_input).val() == $(event.data.fake_input).attr('data-default')) {
  204. $(event.data.fake_input).val('');
  205. }
  206. $(event.data.fake_input).css('color', '#000000');
  207. });
  208. if (settings.autocomplete_url != undefined) {
  209. autocomplete_options = {source: settings.autocomplete_url};
  210. for (attrname in settings.autocomplete) {
  211. autocomplete_options[attrname] = settings.autocomplete[attrname];
  212. }
  213. if (jQuery.Autocompleter !== undefined) {
  214. $(data.fake_input).autocomplete(settings.autocomplete_url, settings.autocomplete);
  215. $(data.fake_input).bind('result', data, function (event, data, formatted) {
  216. if (data) {
  217. $('#' + id).addTag(data[0] + "", {focus: true, unique: (settings.unique)});
  218. }
  219. });
  220. } else if (jQuery.ui.autocomplete !== undefined) {
  221. $(data.fake_input).autocomplete(autocomplete_options);
  222. $(data.fake_input).bind('autocompleteselect', data, function (event, ui) {
  223. $(event.data.real_input).addTag(ui.item.value, {focus: true, unique: (settings.unique)});
  224. return false;
  225. });
  226. }
  227. } else {
  228. // if a user tabs out of the field, create a new tag
  229. // this is only available if autocomplete is not used.
  230. $(data.fake_input).bind('blur', data, function (event) {
  231. var d = $(this).attr('data-default');
  232. if ($(event.data.fake_input).val() != '' && $(event.data.fake_input).val() != d) {
  233. if ((event.data.minChars <= $(event.data.fake_input).val().length) && (!event.data.maxChars || (event.data.maxChars >= $(event.data.fake_input).val().length)))
  234. $(event.data.real_input).addTag($(event.data.fake_input).val(), {
  235. focus: true,
  236. unique: (settings.unique)
  237. });
  238. } else {
  239. $(event.data.fake_input).val($(event.data.fake_input).attr('data-default'));
  240. $(event.data.fake_input).css('color', settings.placeholderColor);
  241. }
  242. return false;
  243. });
  244. }
  245. // if user types a comma, create a new tag
  246. $(data.fake_input).bind('keypress', data, function (event) {
  247. if (event.which == event.data.delimiter.charCodeAt(0) || event.which == 13) {
  248. event.preventDefault();
  249. if ((event.data.minChars <= $(event.data.fake_input).val().length) && (!event.data.maxChars || (event.data.maxChars >= $(event.data.fake_input).val().length)))
  250. $(event.data.real_input).addTag($(event.data.fake_input).val(), {
  251. focus: true,
  252. unique: (settings.unique)
  253. });
  254. $(event.data.fake_input).resetAutosize(settings);
  255. return false;
  256. } else if (event.data.autosize) {
  257. $(event.data.fake_input).doAutosize(settings);
  258. }
  259. });
  260. //Delete last tag on backspace
  261. data.removeWithBackspace && $(data.fake_input).bind('keydown', function (event) {
  262. if (event.keyCode == 8 && $(this).val() == '') {
  263. event.preventDefault();
  264. var last_tag = $(this).closest('.tagsinput').find('.tag:last').text();
  265. var id = $(this).attr('id').replace(/_tag$/, '');
  266. last_tag = last_tag.replace(/[\s]+x$/, '');
  267. $('#' + id).removeTag(escape(last_tag));
  268. $(this).trigger('focus');
  269. }
  270. });
  271. $(data.fake_input).blur();
  272. //Removes the not_valid class when user changes the value of the fake input
  273. if (data.unique) {
  274. $(data.fake_input).keydown(function (event) {
  275. if (event.keyCode == 8 || String.fromCharCode(event.which).match(/\w+|[áéíóúÁÉÍÓÚñÑ,/]+/)) {
  276. $(this).removeClass('not_valid');
  277. }
  278. });
  279. }
  280. } // if settings.interactive
  281. });
  282. return this;
  283. };
  284. $.fn.tagsInput.updateTagsField = function (obj, tagslist) {
  285. var id = $(obj).attr('id');
  286. $(obj).val(tagslist.join(delimiter[id]));
  287. };
  288. $.fn.tagsInput.importTags = function (obj, val) {
  289. $(obj).val('');
  290. var id = $(obj).attr('id');
  291. var tags = val.split(delimiter[id]);
  292. for (i = 0; i < tags.length; i++) {
  293. $(obj).addTag(tags[i], {focus: false, callback: false});
  294. }
  295. if (tags_callbacks[id] && tags_callbacks[id]['onChange']) {
  296. var f = tags_callbacks[id]['onChange'];
  297. f.call(obj, obj, tags[i]);
  298. }
  299. };
  300. })(jQuery);