File indexing completed on 2024-05-19 06:00:29

0001 /*
0002 
0003         jQuery Tags Input Plugin 1.3.3
0004         
0005         Copyright (c) 2011 XOXCO, Inc
0006         
0007         Documentation for this plugin lives here:
0008         http://xoxco.com/clickable/jquery-tags-input
0009         
0010         Licensed under the MIT license:
0011         http://www.opensource.org/licenses/mit-license.php
0012 
0013         ben@xoxco.com
0014 
0015 */
0016 
0017 (function($) {
0018 
0019         var delimiter = new Array();
0020         var tags_callbacks = new Array();
0021         $.fn.doAutosize = function(o){
0022             var minWidth = $(this).data('minwidth'),
0023                 maxWidth = $(this).data('maxwidth'),
0024                 val = '',
0025                 input = $(this),
0026                 testSubject = $('#'+$(this).data('tester_id'));
0027         
0028             if (val === (val = input.val())) {return;}
0029         
0030             // Enter new content into testSubject
0031             var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,' ').replace(/</g, '&lt;').replace(/>/g, '&gt;');
0032             testSubject.html(escaped);
0033             // Calculate new width + whether to change
0034             var testerWidth = testSubject.width(),
0035                 newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
0036                 currentWidth = input.width(),
0037                 isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
0038                                      || (newWidth > minWidth && newWidth < maxWidth);
0039         
0040             // Animate width
0041             if (isValidWidthChange) {
0042                 input.width(newWidth);
0043             }
0044 
0045 
0046   };
0047   $.fn.resetAutosize = function(options){
0048     // alert(JSON.stringify(options));
0049     var minWidth =  $(this).data('minwidth') || options.minInputWidth || $(this).width(),
0050         maxWidth = $(this).data('maxwidth') || options.maxInputWidth || ($(this).closest('.tagsinput').width() - options.inputPadding),
0051         val = '',
0052         input = $(this),
0053         testSubject = $('<tester/>').css({
0054             position: 'absolute',
0055             top: -9999,
0056             left: -9999,
0057             width: 'auto',
0058             fontSize: input.css('fontSize'),
0059             fontFamily: input.css('fontFamily'),
0060             fontWeight: input.css('fontWeight'),
0061             letterSpacing: input.css('letterSpacing'),
0062             whiteSpace: 'nowrap'
0063         }),
0064         testerId = $(this).attr('id')+'_autosize_tester';
0065     if(! $('#'+testerId).length > 0){
0066       testSubject.attr('id', testerId);
0067       testSubject.appendTo('body');
0068     }
0069 
0070     input.data('minwidth', minWidth);
0071     input.data('maxwidth', maxWidth);
0072     input.data('tester_id', testerId);
0073     input.css('width', minWidth);
0074   };
0075   
0076         $.fn.addTag = function(value,options) {
0077                         options = jQuery.extend({focus:false,callback:true},options);
0078                         this.each(function() { 
0079                                 var id = $(this).attr('id');
0080 
0081                                 var tagslist = $(this).val().split(delimiter[id]);
0082                                 if (tagslist[0] == '') { 
0083                                         tagslist = new Array();
0084                                 }
0085 
0086                                 value = jQuery.trim(value);
0087                 
0088                                 if (options.unique) {
0089                                         var skipTag = $(this).tagExist(value);
0090                                         if(skipTag == true) {
0091                                             //Marks fake input as not_valid to let styling it
0092                                     $('#'+id+'_tag').addClass('not_valid');
0093                                 }
0094                                 } else {
0095                                         var skipTag = false; 
0096                                 }
0097                                 
0098                                 if (value !='' && skipTag != true) { 
0099                     $('<span>').addClass('tag').append(
0100                         $('<span>').text(value).append('&nbsp;&nbsp;'),
0101                         $('<a class="tagsinput-remove-link">', {
0102                             href  : '#',
0103                             title : 'Remove tag',
0104                             text  : ''
0105                         }).click(function () {
0106                             return $('#' + id).removeTag(escape(value));
0107                         })
0108                     ).insertBefore('#' + id + '_addTag');
0109 
0110                                         tagslist.push(value);
0111                                 
0112                                         $('#'+id+'_tag').val('');
0113                                         if (options.focus) {
0114                                                 $('#'+id+'_tag').focus();
0115                                         } else {                
0116                                                 $('#'+id+'_tag').blur();
0117                                         }
0118                                         
0119                                         $.fn.tagsInput.updateTagsField(this,tagslist);
0120                                         
0121                                         if (options.callback && tags_callbacks[id] && tags_callbacks[id]['onAddTag']) {
0122                                                 var f = tags_callbacks[id]['onAddTag'];
0123                                                 f.call(this, value);
0124                                         }
0125                                         if(tags_callbacks[id] && tags_callbacks[id]['onChange'])
0126                                         {
0127                                                 var i = tagslist.length;
0128                                                 var f = tags_callbacks[id]['onChange'];
0129                                                 f.call(this, $(this), tagslist[i-1]);
0130                                         }                                       
0131                                 }
0132                 
0133                         });             
0134                         
0135                         return false;
0136                 };
0137                 
0138         $.fn.removeTag = function(value) { 
0139                         value = unescape(value);
0140                         this.each(function() { 
0141                                 var id = $(this).attr('id');
0142         
0143                                 var old = $(this).val().split(delimiter[id]);
0144                                         
0145                                 $('#'+id+'_tagsinput .tag').remove();
0146                                 str = '';
0147                                 for (i=0; i< old.length; i++) { 
0148                                         if (old[i]!=value) { 
0149                                                 str = str + delimiter[id] +old[i];
0150                                         }
0151                                 }
0152                                 
0153                                 $.fn.tagsInput.importTags(this,str);
0154 
0155                                 if (tags_callbacks[id] && tags_callbacks[id]['onRemoveTag']) {
0156                                         var f = tags_callbacks[id]['onRemoveTag'];
0157                                         f.call(this, value);
0158                                 }
0159                         });
0160                                         
0161                         return false;
0162                 };
0163         
0164         $.fn.tagExist = function(val) {
0165                 var id = $(this).attr('id');
0166                 var tagslist = $(this).val().split(delimiter[id]);
0167                 return (jQuery.inArray(val, tagslist) >= 0); //true when tag exists, false when not
0168         };
0169         
0170         // clear all existing tags and import new ones from a string
0171         $.fn.importTags = function(str) {
0172                 id = $(this).attr('id');
0173                 $('#'+id+'_tagsinput .tag').remove();
0174                 $.fn.tagsInput.importTags(this,str);
0175         }
0176                 
0177         $.fn.tagsInput = function(options) { 
0178     var settings = jQuery.extend({
0179       interactive:true,
0180       defaultText:'',
0181       minChars:0,
0182       width:'',
0183       height:'',
0184       autocomplete: {selectFirst: false },
0185       'hide':true,
0186       'delimiter':',',
0187       'unique':true,
0188       removeWithBackspace:true,
0189       placeholderColor:'#666666',
0190       autosize: true,
0191       comfortZone: 20,
0192       inputPadding: 6*2
0193     },options);
0194 
0195                 this.each(function() { 
0196                         if (settings.hide) { 
0197                                 $(this).hide();                         
0198                         }
0199                         var id = $(this).attr('id');
0200                         if (!id || delimiter[$(this).attr('id')]) {
0201                                 id = $(this).attr('id', 'tags' + new Date().getTime()).attr('id');
0202                         }
0203                         
0204                         var data = jQuery.extend({
0205                                 pid:id,
0206                                 real_input: '#'+id,
0207                                 holder: '#'+id+'_tagsinput',
0208                                 input_wrapper: '#'+id+'_addTag',
0209                                 fake_input: '#'+id+'_tag'
0210                         },settings);
0211         
0212                         delimiter[id] = data.delimiter;
0213                         
0214                         if (settings.onAddTag || settings.onRemoveTag || settings.onChange) {
0215                                 tags_callbacks[id] = new Array();
0216                                 tags_callbacks[id]['onAddTag'] = settings.onAddTag;
0217                                 tags_callbacks[id]['onRemoveTag'] = settings.onRemoveTag;
0218                                 tags_callbacks[id]['onChange'] = settings.onChange;
0219                         }
0220         
0221             var containerClass = $('#'+id).attr('class').replace('tagsinput', '');
0222                         var markup = '<div id="'+id+'_tagsinput" class="tagsinput '+containerClass+'"><div class="tagsinput-add-container" id="'+id+'_addTag"><div class="tagsinput-add"></div>';
0223                         
0224                         if (settings.interactive) {
0225                                 markup = markup + '<input id="'+id+'_tag" value="" data-default="'+settings.defaultText+'" />';
0226                         }
0227                         
0228                         markup = markup + '</div></div>';
0229                         
0230                         $(markup).insertAfter(this);
0231 
0232                         $(data.holder).css('width',settings.width);
0233                         $(data.holder).css('min-height',settings.height);
0234                         $(data.holder).css('height','100%');
0235         
0236                         if ($(data.real_input).val()!='') { 
0237                                 $.fn.tagsInput.importTags($(data.real_input),$(data.real_input).val());
0238                         }               
0239                         if (settings.interactive) { 
0240                                 $(data.fake_input).val($(data.fake_input).attr('data-default'));
0241                                 $(data.fake_input).css('color',settings.placeholderColor);
0242                         $(data.fake_input).resetAutosize(settings);
0243                 
0244                                 $(data.holder).bind('click',data,function(event) {
0245                                         $(event.data.fake_input).focus();
0246                                 });
0247                         
0248                                 $(data.fake_input).bind('focus',data,function(event) {
0249                                         if ($(event.data.fake_input).val()==$(event.data.fake_input).attr('data-default')) { 
0250                                                 $(event.data.fake_input).val('');
0251                                         }
0252                                         $(event.data.fake_input).css('color','#000000');                
0253                                 });
0254                                                 
0255                                 if (settings.autocomplete_url != undefined) {
0256                                         autocomplete_options = {source: settings.autocomplete_url};
0257                                         for (attrname in settings.autocomplete) { 
0258                                                 autocomplete_options[attrname] = settings.autocomplete[attrname]; 
0259                                         }
0260                                 
0261                                         if (jQuery.Autocompleter !== undefined) {
0262                                                 $(data.fake_input).autocomplete(settings.autocomplete_url, settings.autocomplete);
0263                                                 $(data.fake_input).bind('result',data,function(event,data,formatted) {
0264                                                         if (data) {
0265                                                                 $('#'+id).addTag(data[0] + "",{focus:true,unique:(settings.unique)});
0266                                                         }
0267                                                 });
0268                                         } else if (jQuery.ui.autocomplete !== undefined) {
0269                                                 $(data.fake_input).autocomplete(autocomplete_options);
0270                                                 $(data.fake_input).bind('autocompleteselect',data,function(event,ui) {
0271                                                         $(event.data.real_input).addTag(ui.item.value,{focus:true,unique:(settings.unique)});
0272                                                         return false;
0273                                                 });
0274                                         }
0275                                 
0276                                         
0277                                 } else {
0278                                                 // if a user tabs out of the field, create a new tag
0279                                                 // this is only available if autocomplete is not used.
0280                                                 $(data.fake_input).bind('blur',data,function(event) { 
0281                                                         var d = $(this).attr('data-default');
0282                                                         if ($(event.data.fake_input).val()!='' && $(event.data.fake_input).val()!=d) { 
0283                                                                 if( (event.data.minChars <= $(event.data.fake_input).val().length) && (!event.data.maxChars || (event.data.maxChars >= $(event.data.fake_input).val().length)) )
0284                                                                         $(event.data.real_input).addTag($(event.data.fake_input).val(),{focus:true,unique:(settings.unique)});
0285                                                         } else {
0286                                                                 $(event.data.fake_input).val($(event.data.fake_input).attr('data-default'));
0287                                                                 $(event.data.fake_input).css('color',settings.placeholderColor);
0288                                                         }
0289                                                         return false;
0290                                                 });
0291                                 
0292                                 }
0293                                 // if user types a comma, create a new tag
0294                                 $(data.fake_input).bind('keypress',data,function(event) {
0295                                         if (event.which==event.data.delimiter.charCodeAt(0) || event.which==13 ) {
0296                                             event.preventDefault();
0297                                                 if( (event.data.minChars <= $(event.data.fake_input).val().length) && (!event.data.maxChars || (event.data.maxChars >= $(event.data.fake_input).val().length)) )
0298                                                         $(event.data.real_input).addTag($(event.data.fake_input).val(),{focus:true,unique:(settings.unique)});
0299                                                 $(event.data.fake_input).resetAutosize(settings);
0300                                                 return false;
0301                                         } else if (event.data.autosize) {
0302                                     $(event.data.fake_input).doAutosize(settings);
0303             
0304                                 }
0305                                 });
0306                                 //Delete last tag on backspace
0307                                 data.removeWithBackspace && $(data.fake_input).bind('keydown', function(event)
0308                                 {
0309                                         if(event.keyCode == 8 && $(this).val() == '')
0310                                         {
0311                                                  event.preventDefault();
0312                                                  var last_tag = $(this).closest('.tagsinput').find('.tag:last').text();
0313                                                  var id = $(this).attr('id').replace(/_tag$/, '');
0314                                                  last_tag = last_tag.replace(/[\s\u00a0]+x$/, '');
0315                                                  $('#' + id).removeTag(escape(last_tag));
0316                                                  $(this).trigger('focus');
0317                                         }
0318                                 });
0319                                 $(data.fake_input).blur();
0320                                 
0321                                 //Removes the not_valid class when user changes the value of the fake input
0322                                 if(data.unique) {
0323                                     $(data.fake_input).keydown(function(event){
0324                                         if(event.keyCode == 8 || String.fromCharCode(event.which).match(/\w+|[áéíóúÁÉÍÓÚñÑ,/]+/)) {
0325                                             $(this).removeClass('not_valid');
0326                                         }
0327                                     });
0328                                 }
0329                         } // if settings.interactive
0330                 });
0331                         
0332                 return this;
0333         
0334         };
0335         
0336         $.fn.tagsInput.updateTagsField = function(obj,tagslist) { 
0337                 var id = $(obj).attr('id');
0338                 $(obj).val(tagslist.join(delimiter[id]));
0339         };
0340         
0341         $.fn.tagsInput.importTags = function(obj,val) {                 
0342                 $(obj).val('');
0343                 var id = $(obj).attr('id');
0344                 var tags = val.split(delimiter[id]);
0345                 for (i=0; i<tags.length; i++) { 
0346                         $(obj).addTag(tags[i],{focus:false,callback:false});
0347                 }
0348                 if(tags_callbacks[id] && tags_callbacks[id]['onChange'])
0349                 {
0350                         var f = tags_callbacks[id]['onChange'];
0351                         f.call(obj, obj, tags[i]);
0352                 }
0353         };
0354 
0355 })(jQuery);