diff options
Diffstat (limited to 'radicale_web/web/infcloud/lib/jquery.tagsinput.js')
-rw-r--r-- | radicale_web/web/infcloud/lib/jquery.tagsinput.js | 436 |
1 files changed, 436 insertions, 0 deletions
diff --git a/radicale_web/web/infcloud/lib/jquery.tagsinput.js b/radicale_web/web/infcloud/lib/jquery.tagsinput.js new file mode 100644 index 0000000..1493079 --- /dev/null +++ b/radicale_web/web/infcloud/lib/jquery.tagsinput.js @@ -0,0 +1,436 @@ +/* + + 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<value.length; i++) + { + if(value[i]==inputDelimiter || value[i]=='\\') + output+='\\'; + + output+=value[i]; + } + return output; + } + + // split and unescape values + String.prototype.splitCustom=function(inputDelimiter) + { + var outputArray=new Array(), + value=this, + j=0; + + for(var i=0; i<value.length; i++) + { + if(value[i]==inputDelimiter) + { + if(outputArray[j]==undefined) + outputArray[j]=''; + ++j; + continue; + } + else if(value[i]=='\\') + ++i; + + outputArray[j]=(outputArray[j]==undefined ? '' : outputArray[j])+value[i]; + } + return outputArray; + } + + $.fn.doAutosize=function(o) + { + var minWidth=$(this).data('minwidth'), + maxWidth=$(this).data('maxwidth'), + val='', + input=$(this), + testSubject=$('#'+$(this).data('tester_id')); + + if(val===(val=input.val())) + return; + + // Enter new content into testSubject + var escaped=val.replace(/\s/g,' '); // get proper width for values with leading spaces (or only spaces) + testSubject.html(escaped); + + // Calculate new width + whether to change + var testerWidth=testSubject.width(), + newWidth=(testerWidth+o.comfortZone)>=minWidth ? testerWidth+o.comfortZone : minWidth, + currentWidth=input.width(), + isValidWidthChange=(newWidth<currentWidth && newWidth>=minWidth) || (newWidth>minWidth && newWidth<maxWidth); + + // Animate width + if(isValidWidthChange) + input.width(newWidth); + }; + + $.fn.resetAutosize=function(options) + { + // alert(JSON.stringify(options)); + var minWidth=$(this).data('minwidth') || options.minInputWidth || $(this).width(), + maxWidth=$(this).data('maxwidth') || options.maxInputWidth || ($(this).closest('.tagsinput').width()-options.inputPadding), + val='', + input=$(this), + testSubject=$('<tester/>').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) + { + $('<span>').addClass('tag').append( + $('<span>').text(value), + $('<a>', { + 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<old.length; i++) + if(old[i]!=value) + str=(str=='' ? '' : str+tags_settings[id].delimiter)+(tags_settings[id].allowDelimiterInValue==true ? old[i].escapeCustom(tags_settings[id].delimiter) : old[i]); + + $.fn.tagsInput.importTags(this, str); + if(tags_callbacks[id] && tags_callbacks[id]['onRemoveTag']) + { + var f=tags_callbacks[id]['onRemoveTag']; + f.call(this, value); + } + }); + return false; + }; + + $.fn.tagExist=function(val) + { + return (jQuery.inArray(val, $(this))>=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='<div id="'+id+'_tagsinput" class="tagsinput"><div id="'+id+'_addTag">'; + if(settings.interactive) + markup=markup+'<div class="input_container"><input id="'+id+'_tag" type="text" value=""'+(settings.useNativePlaceholder==true ? ' placeholder="'+settings.defaultText+'" data-default=""' : ' data-default="'+settings.defaultText+'"')+' /></div>'; + markup=markup+'</div><div class="tags_clear"></div></div>'; + + 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<tagslist.length;i++) + tagslist[i]=tagslist[i].escapeCustom(tags_settings[id].delimiter); + + $(obj).val(tagslist.join(tags_settings[id].delimiter)); + }; + + $.fn.tagsInput.importTags=function(obj, val) + { + var settings=jQuery.extend({ + trimInput: true, + unique: true + }, $(obj).data('tagsOptions')); + + $(obj).val(''); + var id=$(obj).attr('id'); + + if(tags_settings[id].allowDelimiterInValue==true) + var tags=val.splitCustom(tags_settings[id].delimiter); + else + var tags=val.split(delimiter[id]); + + for(var i=0; i<tags.length; i++) + $(obj).addTag(tags[i], {focus: true, unique: settings.unique, trimInput: settings.trimInput, callback: false, imported: true}); + if(tags_callbacks[id] && tags_callbacks[id]['onChange']) + { + var f=tags_callbacks[id]['onChange']; + f.call(obj, tags[i], true); + } + }; +})(jQuery); |