From e95f88053a941f5876fad26af435d433b14afc8a Mon Sep 17 00:00:00 2001 From: vAugagneur Date: Tue, 22 Nov 2011 19:33:19 +0000 Subject: [PATCH] // --- js/jquery/plugins/tagify/jquery.tagify.css | 36 ++++++ js/jquery/plugins/tagify/jquery.tagify.js | 143 +++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100755 js/jquery/plugins/tagify/jquery.tagify.css create mode 100755 js/jquery/plugins/tagify/jquery.tagify.js diff --git a/js/jquery/plugins/tagify/jquery.tagify.css b/js/jquery/plugins/tagify/jquery.tagify.css new file mode 100755 index 000000000..5dbd9bfa1 --- /dev/null +++ b/js/jquery/plugins/tagify/jquery.tagify.css @@ -0,0 +1,36 @@ +/* Tagify styles +Author: Alicia Liu +*/ + +.tagify-container { + width: 300px; + height: 100px; + border: 1px solid #CCC; + background-color: #FFF; + border-radius: 2px; + font-family: Verdana, sans-serif; + font-size: 12px; + overflow: auto; +} +.tagify-container > span { + display: inline-block; + padding: 3px 5px; + margin: 3px; + border-radius: 2px; + border: 1px solid #EEE; + background-color: #FFEBA1; + color: #888; +} +.tagify-container > span > a { + padding-left: 5px; + color: #EB7E14; + text-decoration: none; + font-weight: bold; +} +.tagify-container > input { + border: 0 none; + width: 100px; +} +.tagify-container > input:focus { + outline: none; +} \ No newline at end of file diff --git a/js/jquery/plugins/tagify/jquery.tagify.js b/js/jquery/plugins/tagify/jquery.tagify.js new file mode 100755 index 000000000..87eea42b0 --- /dev/null +++ b/js/jquery/plugins/tagify/jquery.tagify.js @@ -0,0 +1,143 @@ +/* Author: Alicia Liu */ + +(function ($) { + + $.widget("ui.tagify", { + options: { + delimiters: [13, 188], // what user can type to complete a tag in char codes: [enter], [comma] + outputDelimiter: ',', // delimiter for tags in original input field + cssClass: 'tagify-container', // CSS class to style the tagify div and tags, see stylesheet + addTagPrompt: 'add tags' // placeholder text + }, + + _create: function() { + var self = this, + el = self.element, + opts = self.options; + + this.tags = []; + + // hide text field and replace with a div that contains it's own input field for entering tags + this.tagInput = $("") + .attr( 'placeholder', opts.addTagPrompt ) + .keypress( function(e) { + var $this = $(this), + pressed = e.which; + + for ( i in opts.delimiters ) { + + if (pressed == opts.delimiters[i]) { + self.add( $this.val() ); + e.preventDefault(); + return false; + } + } + }) + // for some reason, in Safari, backspace is only recognized on keyup + .keyup( function(e) { + var $this = $(this), + pressed = e.which; + + // if backspace is hit with no input, remove the last tag + if (pressed == 8) { // backspace + if ( $this.val() == "" ) { + self.remove(); + return false; + } + return; + } + }); + + this.tagDiv = $("
") + .addClass( opts.cssClass ) + .click( function() { + $(this).children('input').focus(); + }) + .append( this.tagInput ) + .insertAfter( el.hide() ); + + // if the field isn't empty, parse the field for tags, and prepopulate existing tags + var initVal = $.trim( el.val() ); + + if ( initVal ) { + var initTags = initVal.split( opts.outputDelimiter ); + $.each( initTags, function(i, tag) { + self.add( tag ); + }); + } + }, + + _setOption: function( key, value ) { + options.key = value; + }, + + // add a tag, public function + add: function(text) { + var self = this; + text = text || self.tagInput.val(); + if (text) { + var tagIndex = self.tags.length; + + var removeButton = $("x") + .click( function() { + self.remove( tagIndex ); + return false; + }); + var newTag = $("") + .text( text ) + .append( removeButton ); + + self.tagInput.before( newTag ); + self.tags.push( text ); + self.tagInput.val(''); + } + }, + + // remove a tag by index, public function + // if index is blank, remove the last tag + remove: function( tagIndex ) { + var self = this; + if ( tagIndex == null || tagIndex === (self.tags.length - 1) ) { + this.tagDiv.children("span").last().remove(); + self.tags.pop(); + } + if ( typeof(tagIndex) == 'number' ) { + // otherwise just hide this tag, and we don't mess up the index + this.tagDiv.children( "span:eq(" + tagIndex + ")" ).hide(); + // we rely on the serialize function to remove null values + delete( self.tags[tagIndex] ); + } + }, + + // serialize the tags with the given delimiter, and write it back into the tagified field + serialize: function() { + var self = this; + var delim = self.options.outputDelimiter; + var tagsStr = self.tags.join( delim ); + + // our tags might have deleted entries, remove them here + var dupes = new RegExp(delim + delim + '+', 'g'); // regex: /,,+/g + var ends = new RegExp('^' + delim + '|' + delim + '$', 'g'); // regex: /^,|,$/g + var outputStr = tagsStr.replace( dupes, delim ).replace(ends, ''); + + self.element.val(outputStr); + return outputStr; + }, + + inputField: function() { + return this.tagInput; + }, + + containerDiv: function() { + return this.tagDiv; + }, + + // remove the div, and show original input + destroy: function() { + $.Widget.prototype.destroy.apply(this); + this.tagDiv.remove(); + this.element.show(); + } + }); + +})(jQuery); \ No newline at end of file