(function ($) { "use strict"; var defaultOptions = { tagClass: function(item) { return 'label label-info'; }, itemValue: function(item) { return item ? item.toString() : item; }, itemText: function(item) { return this.itemValue(item); }, freeInput : true }; function TagsInput(element, options) { this.itemsArray = []; this.$element = $(element); this.$element.hide(); this.isSelect = (element.tagName === 'SELECT'); this.multiple = (this.isSelect && element.hasAttribute('multiple')); this.objectItems = options && options.itemValue; this.$container = $('
'); this.$input = $('').appendTo(this.$container); this.$element.after(this.$container); this.build(options); } TagsInput.prototype = { constructor: TagsInput, add: function(item, dontPushVal) { var self = this; // Ignore falsey values, except false if (item !== false && !item) return; // Throw an error when trying to add an object while the itemValue option was not set if (typeof item === "object" && !self.objectItems) throw("Can't add objects when itemValue option is not set"); // Ignore strings only containg whitespace if (item.toString().match(/^\s*$/)) return; // If SELECT but not multiple, remove current tag if (self.isSelect && !self.multiple && self.itemsArray.length > 0) self.remove(self.itemsArray[0]); if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { var items = item.split(','); if (items.length > 1) { for (var i = 0; i < items.length; i++) { this.add(items[i], true); } if (!dontPushVal) self.pushVal(); return; } } // Ignore items allready added var itemValue = self.options.itemValue(item), itemText = self.options.itemText(item), tagClass = self.options.tagClass(item); if ($.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]) return; // register item in internal array and map self.itemsArray.push(item); // add a tag element var $tag = $('' + htmlEncode(itemText) + ''); $tag.data('item', item); self.$input.before($tag); // add