/* jQuery Tags Input Plugin 1.3.3 (with minor modifications for CardDavMATE) Copyright (c) 2011 XOXCO, Inc Documentation for this plugin lives here: http://xoxco.com/clickable/jquery-tags-input Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php ben@xoxco.com */ (function($){ var tags_settings=new Array(); var tags_callbacks=new Array(); String.prototype.escapeCustom=function(inputDelimiter) { var value=(this==undefined ? '' : this), output=''; for(var i=0; i=minWidth ? testerWidth+o.comfortZone : minWidth, currentWidth=input.width(), isValidWidthChange=(newWidth=minWidth) || (newWidth>minWidth && newWidth').css({ position: 'absolute', top: -9999, left: -9999, width: 'auto', fontSize: input.css('fontSize'), fontFamily: input.css('fontFamily'), fontWeight: input.css('fontWeight'), letterSpacing: input.css('letterSpacing'), whiteSpace: 'nowrap' }), testerId=$(this).attr('id')+'_autosize_tester'; if(!$('#'+testerId).length>0) { testSubject.attr('id', testerId); testSubject.appendTo('body'); } input.data('minwidth', minWidth); input.data('maxwidth', maxWidth); input.data('tester_id', testerId); input.css('width', minWidth); }; $.fn.addTag=function(value, options) { options=jQuery.extend({focus: false, callback: true, imported: false}, options); this.each(function() { var id=$(this).attr('id'); if(tags_settings[id].allowDelimiterInValue==true) var tagslist=$(this).val().splitCustom(tags_settings[id].delimiter); else var tagslist=$(this).val().split(delimiter[id]); if(tagslist[0]=='') tagslist=new Array(); if(options.trimInput==true) value=jQuery.trim(value); var skipTag=false; var duplicate=$(tagslist).tagExist(value); if(tags_callbacks[id] && tags_callbacks[id]['validateTag']) skipTag=!tags_callbacks[id]['validateTag'].call(this, value, options.imported, duplicate); if(!skipTag && options.unique) skipTag=duplicate; if(skipTag) $(this).parent().find('#'+id+'_tag').addClass('not_valid'); //Marks fake input as not_valid to let styling it if(value!='' && skipTag!=true) { $('').addClass('tag').append( $('').text(value), $('', { href: '#', title: 'Removing tag', text: 'x' }).click(function(){return $('#'+id).removeTag(value)}) ).insertBefore($(this).parent().find('#'+id+'_addTag')); tagslist.push(value); var tmpRef=$(this).parent().find('#'+id+'_tag'); tmpRef.val(''); if(options.focus) tmpRef.focus(); else tmpRef.blur(); $.fn.tagsInput.updateTagsField(this, tagslist); if(options.callback && tags_callbacks[id] && tags_callbacks[id]['onAddTag']) { var f=tags_callbacks[id]['onAddTag']; f.call(this, value); } if(tags_callbacks[id] && tags_callbacks[id]['onChange']) { var i=tagslist.length; var f=tags_callbacks[id]['onChange']; f.call(this, tagslist[i-1], options.imported); } } }); return false; }; $.fn.removeTag = function(value) { this.each(function() { var id=$(this).attr('id'); if(tags_settings[id].allowDelimiterInValue==true) var old=$(this).val().splitCustom(tags_settings[id].delimiter); else var old=$(this).val().split(delimiter[id]); $(this).parent().find('#'+id+'_tagsinput .tag').remove(); var str=''; for(i=0; i=0); //true when tag exists, false when not }; // clear all existing tags and import new ones from a string $.fn.importTags=function(str) { $(this).parent().find('#'+$(this).attr('id')+'_tagsinput .tag').remove(); $.fn.tagsInput.importTags(this, str); } $.fn.tagsInput=function(options) { var settings=jQuery.extend({ interactive: true, defaultText: 'add a tag', useNativePlaceholder:false, minChars: 0, width: '300px', height: '100px', autocomplete: {selectFirst: false}, hide: true, delimiter: ',', allowDelimiterInValue: false, trimInput: true, unique: true, removeWithBackspace: true, color: '#000000', placeholderColor: '#666666', autosize: true, comfortZone: 20, inputPadding: 6*2 }, options); this.each(function() { if(settings.hide) $(this).hide(); var id=$(this).attr('id'); var data=jQuery.extend({ real_inputObj: $(this), pid: id, real_input: '#'+id, holder: '#'+id+'_tagsinput', input_wrapper: '#'+id+'_addTag', fake_input: '#'+id+'_tag' }, settings); tags_settings[id]={delimiter: data.delimiter, allowDelimiterInValue: data.allowDelimiterInValue}; if(settings.onAddTag || settings.onRemoveTag || settings.onChange || settings.validateTag) { tags_callbacks[id] = new Array(); tags_callbacks[id]['onAddTag'] = settings.onAddTag; tags_callbacks[id]['onRemoveTag'] = settings.onRemoveTag; tags_callbacks[id]['onChange'] = settings.onChange; tags_callbacks[id]['validateTag'] = settings.validateTag; } var markup='
'; if(settings.interactive) markup=markup+'
'; markup=markup+'
'; var tmpMarkupObj=$(markup).insertAfter(this); if(settings.width!=null) tmpMarkupObj.css('width', settings.width); if(settings.height!=null) tmpMarkupObj.css('height', settings.height); if($(this).val()!='') $.fn.tagsInput.importTags($(this), $(this).val()); if(settings.interactive) { tmpMarkupObj.val(tmpMarkupObj.attr('data-default')); tmpMarkupObj.css('color', settings.placeholderColor); tmpMarkupObj.resetAutosize(settings); tmpMarkupObj.bind('click', data, function(event) { $(this).find(event.data.fake_input).focus(); }); tmpMarkupObj.find(data.fake_input).bind('focus', data, function(event) { if($(this).val() == $(this).attr('data-default')) $(this).val(''); $(this).css('color', settings.color); }); if(settings.autocomplete_url!=undefined) { var autocomplete_options={source: settings.autocomplete_url}; for(var attrname in settings.autocomplete) autocomplete_options[attrname]=settings.autocomplete[attrname]; if(jQuery.Autocompleter!==undefined) { tmpMarkupObj.find(data.fake_input).autocomplete(settings.autocomplete_url, settings.autocomplete); tmpMarkupObj.find(data.fake_input).bind('result', data, function(event, data, formatted) { if(data) event.data.real_inputObj.addTag(data[0] + "", {focus: true, unique: settings.unique, trimInput: settings.trimInput}); }); } else if(jQuery.ui.autocomplete!==undefined) { tmpMarkupObj.find(data.fake_input).autocomplete(autocomplete_options); tmpMarkupObj.find(data.fake_input).bind('autocompleteselect', data, function(event,ui) { event.data.real_inputObj.addTag(ui.item.value, {focus: true, unique: settings.unique, trimInput: settings.trimInput}); return false; }); } // if a user tabs out of the field, create a new tag // this is only available if autocomplete is not used. tmpMarkupObj.find(data.fake_input).bind('blur', data, function(event) { var d=$(this).attr('data-default'); if($(this).val()!='' && $(this).val()!=d) { if((event.data.minChars<=$(this).val().length) && (!event.data.maxChars || (event.data.maxChars>=$(this).val().length))) event.data.real_inputObj.addTag($(this).val(), {focus: true, unique: settings.unique, trimInput: settings.trimInput}); } else $(this).val($(this).attr('data-default')); $(this).css('color', settings.placeholderColor); return false; }); } // if user types a comma, create a new tag tmpMarkupObj.find(data.fake_input).bind('keypress', data, function(event) { if(settings.allowDelimiterInValue==false && event.which==event.data.delimiter.charCodeAt(0) || event.which==13) { event.preventDefault(); if((event.data.minChars<=$(this).val().length) && (!event.data.maxChars || (event.data.maxChars>=$(this).val().length))) event.data.real_inputObj.addTag($(event.data.fake_input).val(), {focus: true, unique: settings.unique, trimInput: settings.trimInput}); $(this).resetAutosize(settings); return false; } else if(event.data.autosize) $(this).doAutosize(settings); }); //Delete last tag on backspace data.removeWithBackspace && tmpMarkupObj.find(data.fake_input).bind('keydown', data, function(event) { if($(this).closest('.tagsinput').hasClass('readonly')==false && event.keyCode==8 && $(this).val()=='') { event.preventDefault(); var last_tag=$(this).closest('.tagsinput').find('.tag:last').text(); var id=$(this).attr('id').replace(/_tag$/, ''); last_tag=last_tag.replace(/x$/, ''); event.data.real_inputObj.removeTag(last_tag); $(this).trigger('focus'); } }); tmpMarkupObj.find(data.fake_input).blur(); //Removes the not_valid class when user changes the value of the fake input if(data.unique) { tmpMarkupObj.find(data.fake_input).keydown(function(event) { if(event.keyCode==8 || String.fromCharCode(event.which).match(/\w+|[áéíóúÁÉÍÓÚñÑ,/]+/)) $(this).removeClass('not_valid'); }); } } // if settings.interactive // store settings $(this).data('tagsOptions', settings); return false; }); return this; }; $.fn.tagsInput.updateTagsField=function(obj, tagslist) { var id = $(obj).attr('id'); if(tags_settings[id].allowDelimiterInValue==true) for(var i=0;i