uawdijnntqw1x1x1
IP : 216.73.216.110
Hostname : 6.87.74.97.host.secureserver.net
Kernel : Linux 6.87.74.97.host.secureserver.net 4.18.0-553.83.1.el8_10.x86_64 #1 SMP Mon Nov 10 04:22:44 EST 2025 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
home
/
emeraadmin
/
.razor
/
.
/
..
/
www
/
node_modules
/
parse-filepath
/
..
/
..
/
4d695
/
bootstrap-tagsinput.tar
/
/
karma.conf.js000064400000000746151676724710007150 0ustar00module.exports = function(config) { config.set({ basePath: '', frameworks: ['jasmine'], files: [ 'lib/jquery/jquery.js', 'lib/angular/angular.js', 'dist/bootstrap-tagsinput.min.js', 'dist/bootstrap-tagsinput-angular.min.js', 'test/helpers.js', { pattern: 'test/bootstrap-tagsinput/*.tests.js' } ], reporters: ['progress'], port: 9876, logLevel: config.LOG_DEBUG, captureTimeout: 60000 }); }; src/bootstrap-tagsinput.js000064400000053635151676724710011756 0ustar00(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); }, itemTitle: function(item) { return null; }, freeInput: true, addOnBlur: true, maxTags: undefined, maxChars: undefined, confirmKeys: [13, 44], delimiter: ',', delimiterRegex: null, cancelConfirmKeysOnEmpty: false, onTagExists: function(item, $tag) { $tag.hide().fadeIn(); }, trimValue: false, allowDuplicates: false }; /** * Constructor function */ function TagsInput(element, options) { this.isInit = true; 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.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; this.inputSize = Math.max(1, this.placeholderText.length); this.$container = $('<div class="bootstrap-tagsinput"></div>'); this.$input = $('<input type="text" placeholder="' + this.placeholderText + '"/>').appendTo(this.$container); this.$element.before(this.$container); this.build(options); this.isInit = false; } TagsInput.prototype = { constructor: TagsInput, /** * Adds the given item as a new tag. Pass true to dontPushVal to prevent * updating the elements val() */ add: function(item, dontPushVal, options) { var self = this; if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) return; // Ignore falsey values, except false if (item !== false && !item) return; // Trim value if (typeof item === "string" && self.options.trimValue) { item = $.trim(item); } // 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 delimiter = (self.options.delimiterRegex) ? self.options.delimiterRegex : self.options.delimiter; var items = item.split(delimiter); if (items.length > 1) { for (var i = 0; i < items.length; i++) { this.add(items[i], true); } if (!dontPushVal) self.pushVal(); return; } } var itemValue = self.options.itemValue(item), itemText = self.options.itemText(item), tagClass = self.options.tagClass(item), itemTitle = self.options.itemTitle(item); // Ignore items allready added var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; if (existing && !self.options.allowDuplicates) { // Invoke onTagExists if (self.options.onTagExists) { var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); self.options.onTagExists(item, $existingTag); } return; } // if length greater than limit if (self.items().toString().length + item.length + 1 > self.options.maxInputLength) return; // raise beforeItemAdd arg var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options}); self.$element.trigger(beforeItemAddEvent); if (beforeItemAddEvent.cancel) return; // register item in internal array and map self.itemsArray.push(item); // add a tag element var $tag = $('<span class="tag ' + htmlEncode(tagClass) + (itemTitle !== null ? ('" title="' + itemTitle) : '') + '">' + htmlEncode(itemText) + '<span data-role="remove"></span></span>'); $tag.data('item', item); self.findInputWrapper().before($tag); $tag.after(' '); // Check to see if the tag exists in its raw or uri-encoded form var optionExists = ( $('option[value="' + encodeURIComponent(itemValue) + '"]', self.$element).length || $('option[value="' + htmlEncode(itemValue) + '"]', self.$element).length ); // add <option /> if item represents a value not present in one of the <select />'s options if (self.isSelect && !optionExists) { var $option = $('<option selected>' + htmlEncode(itemText) + '</option>'); $option.data('item', item); $option.attr('value', itemValue); self.$element.append($option); } if (!dontPushVal) self.pushVal(); // Add class when reached maxTags if (self.options.maxTags === self.itemsArray.length || self.items().toString().length === self.options.maxInputLength) self.$container.addClass('bootstrap-tagsinput-max'); // If using typeahead, once the tag has been added, clear the typeahead value so it does not stick around in the input. if ($('.typeahead, .twitter-typeahead', self.$container).length) { self.$input.typeahead('val', ''); } if (this.isInit) { self.$element.trigger($.Event('itemAddedOnInit', { item: item, options: options })); } else { self.$element.trigger($.Event('itemAdded', { item: item, options: options })); } }, /** * Removes the given item. Pass true to dontPushVal to prevent updating the * elements val() */ remove: function(item, dontPushVal, options) { var self = this; if (self.objectItems) { if (typeof item === "object") item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == self.options.itemValue(item); } ); else item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == item; } ); item = item[item.length-1]; } if (item) { var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false, options: options }); self.$element.trigger(beforeItemRemoveEvent); if (beforeItemRemoveEvent.cancel) return; $('.tag', self.$container).filter(function() { return $(this).data('item') === item; }).remove(); $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove(); if($.inArray(item, self.itemsArray) !== -1) self.itemsArray.splice($.inArray(item, self.itemsArray), 1); } if (!dontPushVal) self.pushVal(); // Remove class when reached maxTags if (self.options.maxTags > self.itemsArray.length) self.$container.removeClass('bootstrap-tagsinput-max'); self.$element.trigger($.Event('itemRemoved', { item: item, options: options })); }, /** * Removes all items */ removeAll: function() { var self = this; $('.tag', self.$container).remove(); $('option', self.$element).remove(); while(self.itemsArray.length > 0) self.itemsArray.pop(); self.pushVal(); }, /** * Refreshes the tags so they match the text/value of their corresponding * item. */ refresh: function() { var self = this; $('.tag', self.$container).each(function() { var $tag = $(this), item = $tag.data('item'), itemValue = self.options.itemValue(item), itemText = self.options.itemText(item), tagClass = self.options.tagClass(item); // Update tag's class and inner text $tag.attr('class', null); $tag.addClass('tag ' + htmlEncode(tagClass)); $tag.contents().filter(function() { return this.nodeType == 3; })[0].nodeValue = htmlEncode(itemText); if (self.isSelect) { var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; }); option.attr('value', itemValue); } }); }, /** * Returns the items added as tags */ items: function() { return this.itemsArray; }, /** * Assembly value by retrieving the value of each item, and set it on the * element. */ pushVal: function() { var self = this, val = $.map(self.items(), function(item) { return self.options.itemValue(item).toString(); }); self.$element.val(val, true).trigger('change'); }, /** * Initializes the tags input behaviour on the element */ build: function(options) { var self = this; self.options = $.extend({}, defaultOptions, options); // When itemValue is set, freeInput should always be false if (self.objectItems) self.options.freeInput = false; makeOptionItemFunction(self.options, 'itemValue'); makeOptionItemFunction(self.options, 'itemText'); makeOptionFunction(self.options, 'tagClass'); // Typeahead Bootstrap version 2.3.2 if (self.options.typeahead) { var typeahead = self.options.typeahead || {}; makeOptionFunction(typeahead, 'source'); self.$input.typeahead($.extend({}, typeahead, { source: function (query, process) { function processItems(items) { var texts = []; for (var i = 0; i < items.length; i++) { var text = self.options.itemText(items[i]); map[text] = items[i]; texts.push(text); } process(texts); } this.map = {}; var map = this.map, data = typeahead.source(query); if ($.isFunction(data.success)) { // support for Angular callbacks data.success(processItems); } else if ($.isFunction(data.then)) { // support for Angular promises data.then(processItems); } else { // support for functions and jquery promises $.when(data) .then(processItems); } }, updater: function (text) { self.add(this.map[text]); return this.map[text]; }, matcher: function (text) { return (text.toLowerCase().indexOf(this.query.trim().toLowerCase()) !== -1); }, sorter: function (texts) { return texts.sort(); }, highlighter: function (text) { var regex = new RegExp( '(' + this.query + ')', 'gi' ); return text.replace( regex, "<strong>$1</strong>" ); } })); } // typeahead.js if (self.options.typeaheadjs) { var typeaheadConfig = null; var typeaheadDatasets = {}; // Determine if main configurations were passed or simply a dataset var typeaheadjs = self.options.typeaheadjs; if ($.isArray(typeaheadjs)) { typeaheadConfig = typeaheadjs[0]; typeaheadDatasets = typeaheadjs[1]; } else { typeaheadDatasets = typeaheadjs; } self.$input.typeahead(typeaheadConfig, typeaheadDatasets).on('typeahead:selected', $.proxy(function (obj, datum) { if (typeaheadDatasets.valueKey) self.add(datum[typeaheadDatasets.valueKey]); else self.add(datum); self.$input.typeahead('val', ''); }, self)); } self.$container.on('click', $.proxy(function(event) { if (! self.$element.attr('disabled')) { self.$input.removeAttr('disabled'); } self.$input.focus(); }, self)); if (self.options.addOnBlur && self.options.freeInput) { self.$input.on('focusout', $.proxy(function(event) { // HACK: only process on focusout when no typeahead opened, to // avoid adding the typeahead text as tag if ($('.typeahead, .twitter-typeahead', self.$container).length === 0) { self.add(self.$input.val()); self.$input.val(''); } }, self)); } self.$container.on('keydown', 'input', $.proxy(function(event) { var $input = $(event.target), $inputWrapper = self.findInputWrapper(); if (self.$element.attr('disabled')) { self.$input.attr('disabled', 'disabled'); return; } switch (event.which) { // BACKSPACE case 8: if (doGetCaretPosition($input[0]) === 0) { var prev = $inputWrapper.prev(); if (prev.length) { self.remove(prev.data('item')); } } break; // DELETE case 46: if (doGetCaretPosition($input[0]) === 0) { var next = $inputWrapper.next(); if (next.length) { self.remove(next.data('item')); } } break; // LEFT ARROW case 37: // Try to move the input before the previous tag var $prevTag = $inputWrapper.prev(); if ($input.val().length === 0 && $prevTag[0]) { $prevTag.before($inputWrapper); $input.focus(); } break; // RIGHT ARROW case 39: // Try to move the input after the next tag var $nextTag = $inputWrapper.next(); if ($input.val().length === 0 && $nextTag[0]) { $nextTag.after($inputWrapper); $input.focus(); } break; default: // ignore } // Reset internal input's size var textLength = $input.val().length, wordSpace = Math.ceil(textLength / 5), size = textLength + wordSpace + 1; $input.attr('size', Math.max(this.inputSize, $input.val().length)); }, self)); self.$container.on('keypress', 'input', $.proxy(function(event) { var $input = $(event.target); if (self.$element.attr('disabled')) { self.$input.attr('disabled', 'disabled'); return; } var text = $input.val(), maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars; if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached)) { // Only attempt to add a tag if there is data in the field if (text.length !== 0) { self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text); $input.val(''); } // If the field is empty, let the event triggered fire as usual if (self.options.cancelConfirmKeysOnEmpty === false) { event.preventDefault(); } } // Reset internal input's size var textLength = $input.val().length, wordSpace = Math.ceil(textLength / 5), size = textLength + wordSpace + 1; $input.attr('size', Math.max(this.inputSize, $input.val().length)); }, self)); // Remove icon clicked self.$container.on('click', '[data-role=remove]', $.proxy(function(event) { if (self.$element.attr('disabled')) { return; } self.remove($(event.target).closest('.tag').data('item')); }, self)); // Only add existing value as tags when using strings as tags if (self.options.itemValue === defaultOptions.itemValue) { if (self.$element[0].tagName === 'INPUT') { self.add(self.$element.val()); } else { $('option', self.$element).each(function() { self.add($(this).attr('value'), true); }); } } }, /** * Removes all tagsinput behaviour and unregsiter all event handlers */ destroy: function() { var self = this; // Unbind events self.$container.off('keypress', 'input'); self.$container.off('click', '[role=remove]'); self.$container.remove(); self.$element.removeData('tagsinput'); self.$element.show(); }, /** * Sets focus on the tagsinput */ focus: function() { this.$input.focus(); }, /** * Returns the internal input element */ input: function() { return this.$input; }, /** * Returns the element which is wrapped around the internal input. This * is normally the $container, but typeahead.js moves the $input element. */ findInputWrapper: function() { var elt = this.$input[0], container = this.$container[0]; while(elt && elt.parentNode !== container) elt = elt.parentNode; return $(elt); } }; /** * Register JQuery plugin */ $.fn.tagsinput = function(arg1, arg2, arg3) { var results = []; this.each(function() { var tagsinput = $(this).data('tagsinput'); // Initialize a new tags input if (!tagsinput) { tagsinput = new TagsInput(this, arg1); $(this).data('tagsinput', tagsinput); results.push(tagsinput); if (this.tagName === 'SELECT') { $('option', $(this)).attr('selected', 'selected'); } // Init tags from $(this).val() $(this).val($(this).val()); } else if (!arg1 && !arg2) { // tagsinput already exists // no function, trying to init results.push(tagsinput); } else if(tagsinput[arg1] !== undefined) { // Invoke function on existing tags input if(tagsinput[arg1].length === 3 && arg3 !== undefined){ var retVal = tagsinput[arg1](arg2, null, arg3); }else{ var retVal = tagsinput[arg1](arg2); } if (retVal !== undefined) results.push(retVal); } }); if ( typeof arg1 == 'string') { // Return the results from the invoked function calls return results.length > 1 ? results : results[0]; } else { return results; } }; $.fn.tagsinput.Constructor = TagsInput; /** * Most options support both a string or number as well as a function as * option value. This function makes sure that the option with the given * key in the given options is wrapped in a function */ function makeOptionItemFunction(options, key) { if (typeof options[key] !== 'function') { var propertyName = options[key]; options[key] = function(item) { return item[propertyName]; }; } } function makeOptionFunction(options, key) { if (typeof options[key] !== 'function') { var value = options[key]; options[key] = function() { return value; }; } } /** * HtmlEncodes the given value */ var htmlEncodeContainer = $('<div />'); function htmlEncode(value) { if (value) { return htmlEncodeContainer.text(value).html(); } else { return ''; } } /** * Returns the position of the caret in the given input field * http://flightschool.acylt.com/devnotes/caret-position-woes/ */ function doGetCaretPosition(oField) { var iCaretPos = 0; if (document.selection) { oField.focus (); var oSel = document.selection.createRange(); oSel.moveStart ('character', -oField.value.length); iCaretPos = oSel.text.length; } else if (oField.selectionStart || oField.selectionStart == '0') { iCaretPos = oField.selectionStart; } return (iCaretPos); } /** * Returns boolean indicates whether user has pressed an expected key combination. * @param object keyPressEvent: JavaScript event object, refer * http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html * @param object lookupList: expected key combinations, as in: * [13, {which: 188, shiftKey: true}] */ function keyCombinationInList(keyPressEvent, lookupList) { var found = false; $.each(lookupList, function (index, keyCombination) { if (typeof (keyCombination) === 'number' && keyPressEvent.which === keyCombination) { found = true; return false; } if (keyPressEvent.which === keyCombination.which) { var alt = !keyCombination.hasOwnProperty('altKey') || keyPressEvent.altKey === keyCombination.altKey, shift = !keyCombination.hasOwnProperty('shiftKey') || keyPressEvent.shiftKey === keyCombination.shiftKey, ctrl = !keyCombination.hasOwnProperty('ctrlKey') || keyPressEvent.ctrlKey === keyCombination.ctrlKey; if (alt && shift && ctrl) { found = true; return false; } } }); return found; } /** * Initialize tagsinput behaviour on inputs and selects which have * data-role=tagsinput */ $(function() { $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput(); }); })(window.jQuery); src/bootstrap-tagsinput-angular.js000064400000005676151676724710013407 0ustar00angular.module('bootstrap-tagsinput', []) .directive('bootstrapTagsinput', [function() { function getItemProperty(scope, property) { if (!property) return undefined; if (angular.isFunction(scope.$parent[property])) return scope.$parent[property]; return function(item) { return item[property]; }; } return { restrict: 'EA', scope: { model: '=ngModel' }, template: '<select multiple></select>', replace: false, link: function(scope, element, attrs) { $(function() { if (!angular.isArray(scope.model)) scope.model = []; var select = $('select', element); var typeaheadSourceArray = attrs.typeaheadSource ? attrs.typeaheadSource.split('.') : null; var typeaheadSource = typeaheadSourceArray ? (typeaheadSourceArray.length > 1 ? scope.$parent[typeaheadSourceArray[0]][typeaheadSourceArray[1]] : scope.$parent[typeaheadSourceArray[0]]) : null; select.tagsinput(scope.$parent[attrs.options || ''] || { typeahead : { source : angular.isFunction(typeaheadSource) ? typeaheadSource : null }, itemValue: getItemProperty(scope, attrs.itemvalue), itemText : getItemProperty(scope, attrs.itemtext), confirmKeys : getItemProperty(scope, attrs.confirmkeys) ? JSON.parse(attrs.confirmkeys) : [13], tagClass : angular.isFunction(scope.$parent[attrs.tagclass]) ? scope.$parent[attrs.tagclass] : function(item) { return attrs.tagclass; } }); for (var i = 0; i < scope.model.length; i++) { select.tagsinput('add', scope.model[i]); } select.on('itemAdded', function(event) { if (scope.model.indexOf(event.item) === -1) scope.model.push(event.item); }); select.on('itemRemoved', function(event) { var idx = scope.model.indexOf(event.item); if (idx !== -1) scope.model.splice(idx, 1); }); // create a shallow copy of model's current state, needed to determine // diff when model changes var prev = scope.model.slice(); scope.$watch("model", function() { var added = scope.model.filter(function(i) {return prev.indexOf(i) === -1;}), removed = prev.filter(function(i) {return scope.model.indexOf(i) === -1;}), i; prev = scope.model.slice(); // Remove tags no longer in binded model for (i = 0; i < removed.length; i++) { select.tagsinput('remove', removed[i]); } // Refresh remaining tags select.tagsinput('refresh'); // Add new items in model as tags for (i = 0; i < added.length; i++) { select.tagsinput('add', added[i]); } }, true); }); } }; }]); src/bootstrap-tagsinput-typeahead.css000064400000002000151676724710014050 0ustar00.twitter-typeahead .tt-query, .twitter-typeahead .tt-hint { margin-bottom: 0; } .twitter-typeahead .tt-hint { display: none; } .tt-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; list-style: none; font-size: 14px; background-color: #ffffff; border: 1px solid #cccccc; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 4px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); background-clip: padding-box; cursor: pointer; } .tt-suggestion { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.428571429; color: #333333; white-space: nowrap; } .tt-suggestion:hover, .tt-suggestion:focus { color: #ffffff; text-decoration: none; outline: 0; background-color: #428bca; } src/bootstrap-tagsinput.css000064400000002534151676724710012122 0ustar00.bootstrap-tagsinput { background-color: #fff; border: 1px solid #ccc; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); display: inline-block; padding: 4px 6px; color: #555; vertical-align: middle; border-radius: 4px; max-width: 100%; line-height: 22px; cursor: text; } .bootstrap-tagsinput input { border: none; box-shadow: none; outline: none; background-color: transparent; padding: 0 6px; margin: 0; width: auto; max-width: inherit; } .bootstrap-tagsinput.form-control input::-moz-placeholder { color: #777; opacity: 1; } .bootstrap-tagsinput.form-control input:-ms-input-placeholder { color: #777; } .bootstrap-tagsinput.form-control input::-webkit-input-placeholder { color: #777; } .bootstrap-tagsinput input:focus { border: none; box-shadow: none; } .bootstrap-tagsinput .tag { margin-right: 2px; color: white; } .bootstrap-tagsinput .tag [data-role="remove"] { margin-left: 8px; cursor: pointer; } .bootstrap-tagsinput .tag [data-role="remove"]:after { content: "x"; padding: 0px 2px; } .bootstrap-tagsinput .tag [data-role="remove"]:hover { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } .bootstrap-tagsinput .tag [data-role="remove"]:hover:active { box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } package.json000064400000004474151676724710007063 0ustar00{ "_args": [ [ "bootstrap-tagsinput@0.7.1", "C:\\Users\\Ovi-PC\\Downloads\\themekit-master\\themekit" ] ], "_from": "bootstrap-tagsinput@0.7.1", "_id": "bootstrap-tagsinput@0.7.1", "_inBundle": false, "_integrity": "sha1-/+Owa74qEGlF7ygUVoAFqU8hGTc=", "_location": "/bootstrap-tagsinput", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, "raw": "bootstrap-tagsinput@0.7.1", "name": "bootstrap-tagsinput", "escapedName": "bootstrap-tagsinput", "rawSpec": "0.7.1", "saveSpec": null, "fetchSpec": "0.7.1" }, "_requiredBy": [ "/" ], "_resolved": "https://registry.npmjs.org/bootstrap-tagsinput/-/bootstrap-tagsinput-0.7.1.tgz", "_spec": "0.7.1", "_where": "C:\\Users\\Ovi-PC\\Downloads\\themekit-master\\themekit", "author": { "name": "Tim Schlechter" }, "banner": "/*\n * <%= pkg.name %> v<%= pkg.version %> by <%= pkg.author %>\n * <%= pkg.license.url %>\n */\n", "bugs": { "url": "https://github.com/timschlechter/bootstrap-tagsinput/issues" }, "contributors": [ { "name": "Luckner Jr Jean-Baptiste" } ], "description": "jQuery plugin providing a Twitter Bootstrap user interface for managing tags.", "devDependencies": { "bower": "~1.3.8", "grunt": "~0.4.1", "grunt-bower-task": "~0.4.0", "grunt-cli": "~0.1.13", "grunt-contrib-copy": "~0.5.0", "grunt-contrib-uglify": "^0.9.1", "grunt-jquerymanifest": "~0.1.4", "grunt-karma": "~0.8.3", "grunt-zip": "~0.15.0", "karma": "~0.12.19", "karma-jasmine": "~0.1.5", "karma-phantomjs-launcher": "~0.1.3", "phantomjs": "~1.9.7-15" }, "download": "http://timschlechter.github.io/bootstrap-tagsinput/build/bootstrap-tagsinput.zip", "homepage": "http://timschlechter.github.io/bootstrap-tagsinput/examples/", "keywords": [ "tags", "bootstrap", "input", "select", "form" ], "license": "MIT", "main": "dist/bootstrap-tagsinput.js", "name": "bootstrap-tagsinput", "repository": { "type": "git", "url": "git://github.com/timschlechter/bootstrap-tagsinput.git" }, "scripts": { "test": "karma start --single-run --no-auto-watch" }, "title": "Bootstrap Tags Input", "version": "0.7.1" } .travis.yml000064400000000334151676724710006675 0ustar00language: node_js node_js: - 0.10 before_script: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - npm install - ./node_modules/.bin/grunt install script: - ./node_modules/.bin/grunt test test/bootstrap-tagsinput-angular.tests.js000064400000005063151676724710014726 0ustar00describe('bootstrap-tagsinput', function() { // Load the myApp module, which contains the directive beforeEach(module('bootstrap-tagsinput')); describe("with strings as items" , function() { describe("compile with 2 tags in model" , function() { var $scope, $element; beforeEach(inject(function($compile, $rootScope){ $scope = $rootScope; $scope.tags = ['Amsterdam', 'New York']; $element = $compile(angular.element('<bootstrap-tagsinput ng-model="tags" />'))($scope); $scope.$digest(); })); it('should hide the element', function() { expect($element.is(":visible")).toBe(false); }); it('should have 2 tags', function() { expect($('.tag', $element).length).toBe(2); }); }); }); describe("with objects as items" , function() { describe("compile with 2 tags in model" , function() { var $scope, $element; beforeEach(inject(function($compile, $rootScope){ $scope = $rootScope; $scope.tags = [{ value: 1, text: 'Amsterdam'}, { value: 2, text: 'New York'} ]; $element = $compile(angular.element('<bootstrap-tagsinput ng-model="tags" itemvalue="value" itemtext="text"/>'))($scope); $scope.$digest(); })); it('should hide the element', function() { expect($element.is(":visible")).toBe(false); }); it('should have 2 tags', function() { expect($('.tag', $element).length).toBe(2); }); describe("changing a tag's text" , function() { beforeEach(function() { $scope.tags[0].text = 'Paris'; $scope.$digest(); }); it("should update tag's text", function() { expect($('.tag', $element).first().text()).toBe('Paris'); }); }); describe("adding an item to the model" , function() { beforeEach(function() { $scope.tags.push({ value: 3, text: 'Beijing'}); $scope.$digest(); }); it("should add a tag", function() { expect($('.tag', $element).length).toBe(3); }); }); describe("BACKSPACE", function() { beforeEach(function() { $element.tagsinput('focus'); }); it('after last tag, should remove item from model', function() { $('input', $element).trigger($.Event('keydown', { which: 8 })); $scope.$digest(); expect($scope.tags.length).toBe(1); }); }); }); }); });test/bootstrap-tagsinput/input_with_object_items.tests.js000064400000010560151676724710020216 0ustar00describe("bootstrap-tagsinput", function() { describe("with objects as items", function() { testTagsInput('<input type="text" />', function() { it("adding a item should throw an exception", function() { var element = this.$element; expect(function() { element.tagsinput('add', {}); }).toThrow("Can't add objects when itemValue option is not set"); }); }); testTagsInput('<input type="text" />', { itemValue: function(item) { return item.value; } }, function() { describe("adding an item", function() { var item; beforeEach(function() { item = { value: 1 }; this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("val() should return the item's value", function() { expect(this.$element.val()).toBe("1"); }); it("tag's text should be the item's value", function() { expect($('.tag', this.$sandbox).text()).toBe("1"); }); }); }); testTagsInput('<input type="text" />', { itemValue: 'value' }, function() { describe("adding an item", function() { var item; beforeEach(function() { item = { value: 1 }; this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("'items' should returns exactly 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); it("val() should return the item's value", function() { expect(this.$element.val()).toBe("1"); }); it("tag's text should be the item's value", function() { expect($('.tag', this.$sandbox).text()).toBe("1"); }); }); }); testTagsInput('<input type="text" />', { itemValue: function(item) { return item.value; }, itemText: function(item) { return item.text; } }, function() { describe("adding an item", function() { var item = { value: 1, text: 'some' }; beforeEach(function() { this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("val() should return the item's value", function() { expect(this.$element.val()).toBe("1"); }); it("tag's text should be the item's text", function() { expect($('.tag', this.$sandbox).text()).toBe("some"); }); describe("change item and invoke 'refesh'", function() { beforeEach(function() { item.text = 'changed'; this.$element.tagsinput('refresh'); }); it("should update tags's text", function() { expect($('.tag', this.$sandbox).text()).toBe('changed'); }); it("tag should still have remove button", function() { expect($('[data-role=remove]', this.$sandbox)[0]).not.toBeUndefined(); }); }); }); }); testTagsInput('<input type="text" />', { itemValue: function(item) { return item.value; }, itemText: function(item) { return item.text; }, itemTitle: function(item) { return item.title; } }, function() { describe("adding an item with a title", function() { var item; beforeEach(function() { item = { value: 1, text: 'one', title: 'number one' }; this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("'items' should returns exactly 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); it("val() should return the item's value", function() { expect(this.$element.val()).toBe("1"); }); it("tag's text should be the item's value", function() { expect($('.tag', this.$sandbox).text()).toBe("one"); }); it("tag's title should be the item's title", function() { expect($('.tag', this.$sandbox).attr('title')).toBe("number one"); }); }); }); }); });test/bootstrap-tagsinput/reproduced_bugs.tests.js000064400000014511151676724710016451 0ustar00describe("bootstrap-tagsinput", function() { describe("Reproduced bugs", function() { describe("#1: Demo error", function() { testTagsInput('<input type="text" value="some_tag" />', function() { it("clicking remove button should remove item", function() { $('[data-role=remove]', this.$sandbox).trigger('click'); expect(this.$element.tagsinput('items').length).toBe(0); }); it("clicking remove button should remove tag element", function() { $('[data-role=remove]', this.$sandbox).trigger('click'); expect($('.tag', this.$sandbox).length).toBe(0); }); }); }); describe("#11: Cannot remove an item by programming", function() { testTagsInput('<input type="text" />', { itemValue: function(item) { return item.value; } }, function() { describe("add two different objects with same value", function() { var item1 = { value: 1 }, item2 = { value: 1 }; beforeEach(function() { this.$element.tagsinput('add', item1); this.$element.tagsinput('add', item2); }); it("'items' should return the first added item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item1); }); it("'items' should return exactly 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); it("should have exactly 1 tag", function() { expect($('.tag', this.$sandbox).length).toBe(1); }); }); describe("remove item", function() { beforeEach(function() { this.$element.tagsinput('add', { value: 1 }); }); it("by value, should remove then item", function() { this.$element.tagsinput('remove', 1); expect(this.$element.tagsinput('items').length).toBe(0); }); it("by value, should remove then tag", function() { this.$element.tagsinput('remove', 1); expect($('.tag', this.$sandbox).length).toBe(0); }); it("by different instance, should remove then tag", function() { this.$element.tagsinput('remove', { value: 1 }); expect($('.tag', this.$sandbox).length).toBe(0); }); it("should remove items when none of the items have a matching value", function() { this.$element.tagsinput('add', { value: 1 }); this.$element.tagsinput('remove', 2); expect(this.$element.tagsinput('items').length).toBe(1); }); }); }); testTagsInput('<select />', { itemValue: function(item) { return item.value; } }, function() { describe("add two objects", function() { var item1 = { value: 1 }, item2 = { value: 2 }; beforeEach(function() { this.$element.tagsinput('add', item1); this.$element.tagsinput('add', item2); }); it("'items' should return the last added item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item2); }); it("'items' should return exactly 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); it("should have exactly 1 tag", function() { expect($('.tag', this.$sandbox).length).toBe(1); }); it("val() should return first item's value", function() { expect(this.$element.val()).toBe("2"); }); }); }); }); describe("#34: Error in ReloadPage", function() { describe("init tagsinput with objects as items, but with value set on element", function() { testTagsInput('<input type="text" value="1" />', { itemValue: function(item) { return item.value; } }, function() { it("should have no tags", function() { expect(this.$element.tagsinput('items').length).toBe(0); }); }); testTagsInput('<select><option value="1" /></select>', { itemValue: function(item) { return item.value; } }, function() { it("should have no tags", function() { expect(this.$element.tagsinput('items').length).toBe(0); }); }); }); }); describe("#90: Error in reinitialization (arg1 and arg2 are undefined)", function() { describe("init tagsinput twice", function() { testTagsInput('<input type="text" value="1" />', { itemValue: function(item) { return item.value; } }, function() { it("should not fail if an element is reinitialized", function () { this.$element.tagsinput(); }); it("should return the original instance if already initialized", function () { return this.$element.tagsinput() === this; }); }); }); }); describe("#142: Initialization of Null Values for Multi Select field", function() { testTagsInput('<select multiple data-role="tagsinput"></select>', function() { it("Initializing an empty select shouldn't throw an error.", function() { $("select[multiple][data-role=tagsinput]").tagsinput(); }); }); }); describe("#128: Custom classes for tags don't work if entered as strings", function() { testTagsInput('<input type="text" value="1" />', { tagClass: 'big' }, function() { it("should have a tag with class 'big' when using tagClass option as string", function() { expect($(".big", this.$tagsinput).length).toBe(1); }); }); testTagsInput('<input type="text" value="1" />', { tagClass: function() { return 'big'; } }, function() { it("should have a tag with class 'big' when using tagClass option as function", function() { expect($(".big", this.$tagsinput).length).toBe(1); }); }); }); describe("#107: Fixed bug when removing items", function() { testTagsInput('<input type="text" value="yes,no" />', function() { it("should not remove items when remove a non-existing item", function() { this.$element.tagsinput('remove', 'maybe'); expect(this.$element.tagsinput('items').length).toBe(2); }); }); }); }); });test/bootstrap-tagsinput/input_with_string_items.tests.js000064400000017114151676724710020260 0ustar00describe("bootstrap-tagsinput", function() { describe("with strings as items", function() { testTagsInput('<input type="text" />', { trimValue: true }, function(){ it("trim item values", function() { this.$element.tagsinput('add', ' some_tag '); this.$element.tagsinput('add', 'some_tag '); expect(this.$element.val()).toBe('some_tag'); }); }); testTagsInput('<input type="text" />', function() { it("should hide input", function() { expect(this.$element.css('display')).toBe('none'); }); it("should add tag on when pressing ENTER", function() { this.$tagsinput_input.val('some_tag'); this.$tagsinput_input.trigger($.Event('keypress', { which: 13 })); expect(this.$element.tagsinput('items').length).toBe(1); }); it("should add tag on when pressing COMMA ,", function() { this.$tagsinput_input.val('some_tag'); this.$tagsinput_input.trigger($.Event('keypress', { which: 44 })); expect(this.$element.tagsinput('items').length).toBe(1); }); describe("should not add tag", function() { it("when adding same item twice", function() { this.$element.tagsinput('add', 'some_tag'); this.$element.tagsinput('add', 'some_tag'); expect(this.$element.val()).toBe('some_tag'); }); it("when adding empty string", function() { this.$element.tagsinput('add', ''); expect(this.$element.tagsinput('items').length).toBe(0); }); it("when adding whitespace string", function() { this.$element.tagsinput('add', ' '); expect(this.$element.tagsinput('items').length).toBe(0); }); it("when adding undefined", function() { this.$element.tagsinput('add', undefined); expect(this.$element.tagsinput('items').length).toBe(0); }); it("when adding null", function() { this.$element.tagsinput('add', null); expect(this.$element.tagsinput('items').length).toBe(0); }); }); describe("should add tag", function() { it("when adding boolean false", function() { this.$element.tagsinput('add', false); expect(this.$element.tagsinput('items').length).toBe(1); }); it("when adding boolean true", function() { this.$element.tagsinput('add', false); expect(this.$element.tagsinput('items').length).toBe(1); }); }); describe("invoke 'add' with a string", function() { beforeEach(function() { this.$element.tagsinput('add', 'some_tag'); }); it("val() should return 'some_tag'", function() { expect(this.$element.val()).toBe('some_tag'); }); it("'items' should return 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); describe("invoking 'remove'", function() { beforeEach(function() { this.$element.tagsinput('remove', 'some_tag'); }); it("val() should should return null", function() { expect(this.$element.val()).toBe(''); }); }); }); describe("invoke 'add' with a string containing a comma", function() { beforeEach(function() { this.$element.tagsinput('add', 'before,after'); }); it("val() should return 'before,after'", function() { expect(this.$element.val()).toBe('before,after'); }); it("'items' should return 2 items", function() { expect(this.$element.tagsinput('items').length).toBe(2); }); }); it("'focus' should place focus in input", function() { this.$element.tagsinput('focus'); expect(hasFocus(this.$tagsinput_input)).toBe(true); }); }); testTagsInput('<input type="text" value="some,tags" />', function() { it('should have 2 tags', function() { expect(this.$element.tagsinput('items').length).toBe(2); }); describe("invoke 'removeAll'", function() { beforeEach(function() { this.$element.tagsinput('removeAll'); }); it("should remove both tags", function() { expect(this.$element.tagsinput('items').length).toBe(0); }); it("val() should return ''", function() { expect(this.$element.val()).toBe(''); }); }); describe("BACKSPACE", function() { beforeEach(function() { this.$element.tagsinput('focus'); }); it('after last tag, should remove the last tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 8 })); expect(this.$element.tagsinput('items')[0]).toBe('some'); }); it('after last tag, should remove the last tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 8 })); expect(this.$element.tagsinput('items').length).toBe(1); }); it('after first tag, should remove the first tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 37 })); this.$tagsinput_input.trigger($.Event('keydown', { which: 8 })); expect(this.$element.tagsinput('items')[0]).toBe('tags'); }); }); describe("DELETE", function() { beforeEach(function() { this.$element.tagsinput('focus'); // move cursor before last tag this.$tagsinput_input.trigger($.Event('keydown', { which: 37 })); }); it('before last tag, should remove the last tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 46 })); expect(this.$element.tagsinput('items')[0]).toBe('some'); }); it('before last tag, should remove the last tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 46 })); expect(this.$element.tagsinput('items').length).toBe(1); }); it('before first tag, should remove the first tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 37 })); this.$tagsinput_input.trigger($.Event('keydown', { which: 46 })); expect(this.$element.tagsinput('items')[0]).toBe('tags'); }); }); }); testTagsInput('<input type="text" value="some,tag"/>', { maxTags: 2 }, function() { it("should have class 'bootstrap-tagsinput-max'", function() { expect(this.$tagsinput.hasClass('bootstrap-tagsinput-max')).toBe(true); }); describe("adding another tag", function() { it("should not add the tag", function() { this.$element.tagsinput('add', 'another'); expect(this.$element.tagsinput('items').length).toBe(2); }); }); describe("removing a tags", function() { it("should not have class 'bootstrap-tagsinput-max'", function() { this.$element.tagsinput('remove', 'some'); expect(this.$tagsinput.hasClass('bootstrap-tagsinput-max')).toBe(false); }); }) }); testTagsInput('<input type="text" />', { confirmKeys: [9] }, function() { it("should add tag on when pressing TAB", function() { this.$tagsinput_input.val('some_tag'); this.$tagsinput_input.trigger($.Event('keypress', { which: 9 })); expect(this.$element.tagsinput('items').length).toBe(1); }); }); }); }); test/bootstrap-tagsinput/select_with_string_items.tests.js000064400000002747151676724710020406 0ustar00describe("bootstrap-tagsinput", function() { describe("with strings as items", function() { testTagsInput("<select multiple />", function() { describe("when added 1 item", function() { beforeEach(function() { this.$element.tagsinput('add', 'some_tag'); }); it("val() should return array containing 1 item", function() { expect(this.$element.val()[0]).toBe('some_tag'); }); describe("invoking 'remove'", function() { beforeEach(function() { this.$element.tagsinput('remove', 'some_tag'); }); it("val() should should return null", function() { expect(this.$element.val()).toBeNull(); }); it("there should be no <option /> elements", function() { expect($("option", this.$sandbox).length).toBe(0); }); }); }); describe("when added item containing a comma", function() { beforeEach(function() { this.$element.tagsinput('add', 'before,after'); }); it("val() should return array containing 1 item", function() { expect(this.$element.val()[0]).toBe('before,after'); }); }); }); testTagsInput('<select multiple><option value="some">some</option></select>', function() { it('should have one tag', function() { expect(this.$element.tagsinput('items')[0]).toBe('some'); }); }); }); });test/bootstrap-tagsinput/select_with_object_items.tests.js000064400000002655151676724710020344 0ustar00describe("bootstrap-tagsinput", function() { describe("with objects as items", function() { testTagsInput('<select multiple />', { itemValue: function(item) { return item.value; }, itemText: function(item) { return item.text; } }, function() { describe("adding an item", function() { var item; beforeEach(function() { item = { value: 1, text: 'some' }; this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("val() should return the item's value", function() { expect(this.$element.val()[0]).toBe("1"); }); it("tag's text should be the item's text", function() { expect($('.tag', this.$sandbox).text()).toBe("some"); }); describe("change item's value and text and invoke 'refesh'", function() { beforeEach(function() { item.value = 2; item.text = 'changed'; this.$element.tagsinput('refresh'); }); it("should update tags's text", function() { expect($('.tag', this.$sandbox).text()).toBe('changed'); }); it("val() should return item's new value", function() { expect(this.$element.val()[0]).toBe("2"); }); }); }); }); }); });test/bootstrap-tagsinput/events.tests.js000064400000001447151676724710014605 0ustar00describe("bootstrap-tagsinput", function() { describe("events", function() { testTagsInput('<input type="text" />', function() { it("beforeItemAdd canceled", function() { this.$element.on('beforeItemAdd', function(event) { event.cancel = true; }); this.$element.tagsinput('add', 'some'); expect(this.$element.tagsinput('items').length).toBe(0); }); }); testTagsInput('<input type="text" value="1" />', function() { it("beforeItemRemove canceled", function() { this.$element.on('beforeItemRemove', function(event) { event.cancel = true; }); this.$element.tagsinput('remove', '1'); expect(this.$element.tagsinput('items').length).toBe(1); }); }); }); }); test/index.html000064400000003416151676724710007544 0ustar00<!DOCTYPE html> <html> <head> <title>Jasmine Test Runner</title> <meta name="robots" content="noindex, nofollow" /> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="lib/jasmine/lib/jasmine-core/jasmine.css"/> <script type="text/javascript" src="lib/jquery/dist/jquery.min.js"></script> <script type="text/javascript" src="lib/angular/angular.min.js"></script> <script type="text/javascript" src="lib/bootstrap/dist/js/bootstrap.min.js"></script> <script type="text/javascript" src="lib/jasmine/lib/jasmine-core/jasmine.js"></script> <script type="text/javascript" src="lib/jasmine/lib/jasmine-core/jasmine-html.js"></script> <script type="text/javascript" src="lib/jasmine/lib/jasmine-core/boot.js"></script> <script type="text/javascript" src="../src/bootstrap-tagsinput.js"></script> <script type="text/javascript" src="../src/bootstrap-tagsinput-angular.js"></script> <script type="text/javascript" src="helpers.js"></script> <script type="text/javascript" src="bootstrap-tagsinput/input_with_string_items.tests.js"></script> <script type="text/javascript" src="bootstrap-tagsinput/input_with_object_items.tests.js"></script> <script type="text/javascript" src="bootstrap-tagsinput/select_with_string_items.tests.js"></script> <script type="text/javascript" src="bootstrap-tagsinput/select_with_object_items.tests.js"></script> <script type="text/javascript" src="bootstrap-tagsinput/reproduced_bugs.tests.js"></script> <script type="text/javascript" src="bootstrap-tagsinput/events.tests.js"></script> <script type="text/javascript" src="bootstrap-tagsinput-angular.tests.js"></script> </head> <body> </body> </html> test/helpers.js000064400000002237151676724710007547 0ustar00// Creates a new element from the given elementHtml in a sandbox before each // tests defined in the tests function. It initializes it as a tags input with // the given options. function testTagsInput(elementHtml, options, tests) { if (typeof options === 'function') { tests = options; options = undefined; } describe(elementHtml + ' (options: ' + JSON.stringify(options, function(name, value) { return (typeof value === "function") ? value.toString() : value; }) + ')', function() { beforeEach(function() { this.$sandbox = $('<div />').appendTo($('body')); this.$element = $(elementHtml).appendTo(this.$sandbox); this.$element.tagsinput(options); this.$tagsinput = $('.bootstrap-tagsinput', this.$sandbox); this.$tagsinput_input = $('input', this.$tagsinput); }); afterEach(function() { this.$element.tagsinput('destroy'); this.$sandbox.remove(); delete this.$tagsinput_input; delete this.$tagsinput; delete this.$sandbox; delete this.$element; }); tests(); }); } function hasFocus($elt) { return $elt.get(0) === document.activeElement; }bootstrap-tagsinput.jquery.json000064400000001243151676724710013026 0ustar00{ "name": "bootstrap-tagsinput", "version": "0.7.1", "title": "Bootstrap Tags Input", "author": { "name": "Tim Schlechter" }, "licenses": [ { "type": "MIT", "url": "http://opensource.org/licenses/MIT" } ], "dependencies": { "jquery": "*" }, "description": "jQuery plugin providing a Twitter Bootstrap user interface for managing tags.", "keywords": [ "tags", "bootstrap", "input", "select", "form" ], "download": "http://timschlechter.github.io/bootstrap-tagsinput/build/bootstrap-tagsinput.zip", "homepage": "http://timschlechter.github.io/bootstrap-tagsinput/examples/" }LICENSE000064400000002115151676724710005570 0ustar00The MIT License (MIT) Copyright (c) 2013 Tim Schlechter Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Gruntfile.js000064400000004236151676724710007066 0ustar00module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-karma'); grunt.loadNpmTasks('grunt-zip'); grunt.loadNpmTasks('grunt-jquerymanifest'); grunt.loadNpmTasks('grunt-bower-task'); grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), bower: { install: { options: { targetDir: './lib', layout: 'byType', install: true, verbose: true, cleanTargetDir: false, cleanBowerDir: true, bowerOptions: { forceLatest: true } } } }, copy: { build: { files: [ { expand: true, flatten: true, src: ['src/*.*'], dest: 'dist/', filter: 'isFile' } ] } }, uglify: { options: { banner: '<%= pkg.banner %>', sourceMap: 'dist/<%= pkg.name %>.min.js.map', sourceMappingURL: '<%= pkg.name %>.min.js.map' }, build: { files: { 'dist/<%= pkg.name %>.min.js': 'src/<%= pkg.name %>.js', 'dist/<%= pkg.name %>-angular.min.js': 'src/<%= pkg.name %>-angular.js' } } }, karma: { unit: { configFile: 'karma.conf.js', runnerPort: 9999, singleRun: true, autoWatch: false, browsers: ['PhantomJS'] } }, zip: { delpoy: { // cwd: 'dist/', src: [ 'dist/bootstrap-tagsinput*.js', 'dist/bootstrap-tagsinput*.css', 'dist/bootstrap-tagsinput*.less', 'dist/bootstrap-tagsinput*.map' ], dest: 'dist/<%= pkg.name %>.zip' } }, jquerymanifest: { options: { source: grunt.file.readJSON('package.json'), overrides: { title: '<%= pkg.title %>' } } } }); grunt.registerTask('install', ['bower']); grunt.registerTask('compile', ['uglify', 'copy']); grunt.registerTask('test', ['compile', 'karma']); grunt.registerTask('build', ['test', 'jquerymanifest', 'zip']); }; dist/bootstrap-tagsinput.js000064400000053635151676724710012132 0ustar00(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); }, itemTitle: function(item) { return null; }, freeInput: true, addOnBlur: true, maxTags: undefined, maxChars: undefined, confirmKeys: [13, 44], delimiter: ',', delimiterRegex: null, cancelConfirmKeysOnEmpty: false, onTagExists: function(item, $tag) { $tag.hide().fadeIn(); }, trimValue: false, allowDuplicates: false }; /** * Constructor function */ function TagsInput(element, options) { this.isInit = true; 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.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; this.inputSize = Math.max(1, this.placeholderText.length); this.$container = $('<div class="bootstrap-tagsinput"></div>'); this.$input = $('<input type="text" placeholder="' + this.placeholderText + '"/>').appendTo(this.$container); this.$element.before(this.$container); this.build(options); this.isInit = false; } TagsInput.prototype = { constructor: TagsInput, /** * Adds the given item as a new tag. Pass true to dontPushVal to prevent * updating the elements val() */ add: function(item, dontPushVal, options) { var self = this; if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) return; // Ignore falsey values, except false if (item !== false && !item) return; // Trim value if (typeof item === "string" && self.options.trimValue) { item = $.trim(item); } // 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 delimiter = (self.options.delimiterRegex) ? self.options.delimiterRegex : self.options.delimiter; var items = item.split(delimiter); if (items.length > 1) { for (var i = 0; i < items.length; i++) { this.add(items[i], true); } if (!dontPushVal) self.pushVal(); return; } } var itemValue = self.options.itemValue(item), itemText = self.options.itemText(item), tagClass = self.options.tagClass(item), itemTitle = self.options.itemTitle(item); // Ignore items allready added var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; if (existing && !self.options.allowDuplicates) { // Invoke onTagExists if (self.options.onTagExists) { var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); self.options.onTagExists(item, $existingTag); } return; } // if length greater than limit if (self.items().toString().length + item.length + 1 > self.options.maxInputLength) return; // raise beforeItemAdd arg var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options}); self.$element.trigger(beforeItemAddEvent); if (beforeItemAddEvent.cancel) return; // register item in internal array and map self.itemsArray.push(item); // add a tag element var $tag = $('<span class="tag ' + htmlEncode(tagClass) + (itemTitle !== null ? ('" title="' + itemTitle) : '') + '">' + htmlEncode(itemText) + '<span data-role="remove"></span></span>'); $tag.data('item', item); self.findInputWrapper().before($tag); $tag.after(' '); // Check to see if the tag exists in its raw or uri-encoded form var optionExists = ( $('option[value="' + encodeURIComponent(itemValue) + '"]', self.$element).length || $('option[value="' + htmlEncode(itemValue) + '"]', self.$element).length ); // add <option /> if item represents a value not present in one of the <select />'s options if (self.isSelect && !optionExists) { var $option = $('<option selected>' + htmlEncode(itemText) + '</option>'); $option.data('item', item); $option.attr('value', itemValue); self.$element.append($option); } if (!dontPushVal) self.pushVal(); // Add class when reached maxTags if (self.options.maxTags === self.itemsArray.length || self.items().toString().length === self.options.maxInputLength) self.$container.addClass('bootstrap-tagsinput-max'); // If using typeahead, once the tag has been added, clear the typeahead value so it does not stick around in the input. if ($('.typeahead, .twitter-typeahead', self.$container).length) { self.$input.typeahead('val', ''); } if (this.isInit) { self.$element.trigger($.Event('itemAddedOnInit', { item: item, options: options })); } else { self.$element.trigger($.Event('itemAdded', { item: item, options: options })); } }, /** * Removes the given item. Pass true to dontPushVal to prevent updating the * elements val() */ remove: function(item, dontPushVal, options) { var self = this; if (self.objectItems) { if (typeof item === "object") item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == self.options.itemValue(item); } ); else item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == item; } ); item = item[item.length-1]; } if (item) { var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false, options: options }); self.$element.trigger(beforeItemRemoveEvent); if (beforeItemRemoveEvent.cancel) return; $('.tag', self.$container).filter(function() { return $(this).data('item') === item; }).remove(); $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove(); if($.inArray(item, self.itemsArray) !== -1) self.itemsArray.splice($.inArray(item, self.itemsArray), 1); } if (!dontPushVal) self.pushVal(); // Remove class when reached maxTags if (self.options.maxTags > self.itemsArray.length) self.$container.removeClass('bootstrap-tagsinput-max'); self.$element.trigger($.Event('itemRemoved', { item: item, options: options })); }, /** * Removes all items */ removeAll: function() { var self = this; $('.tag', self.$container).remove(); $('option', self.$element).remove(); while(self.itemsArray.length > 0) self.itemsArray.pop(); self.pushVal(); }, /** * Refreshes the tags so they match the text/value of their corresponding * item. */ refresh: function() { var self = this; $('.tag', self.$container).each(function() { var $tag = $(this), item = $tag.data('item'), itemValue = self.options.itemValue(item), itemText = self.options.itemText(item), tagClass = self.options.tagClass(item); // Update tag's class and inner text $tag.attr('class', null); $tag.addClass('tag ' + htmlEncode(tagClass)); $tag.contents().filter(function() { return this.nodeType == 3; })[0].nodeValue = htmlEncode(itemText); if (self.isSelect) { var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; }); option.attr('value', itemValue); } }); }, /** * Returns the items added as tags */ items: function() { return this.itemsArray; }, /** * Assembly value by retrieving the value of each item, and set it on the * element. */ pushVal: function() { var self = this, val = $.map(self.items(), function(item) { return self.options.itemValue(item).toString(); }); self.$element.val(val, true).trigger('change'); }, /** * Initializes the tags input behaviour on the element */ build: function(options) { var self = this; self.options = $.extend({}, defaultOptions, options); // When itemValue is set, freeInput should always be false if (self.objectItems) self.options.freeInput = false; makeOptionItemFunction(self.options, 'itemValue'); makeOptionItemFunction(self.options, 'itemText'); makeOptionFunction(self.options, 'tagClass'); // Typeahead Bootstrap version 2.3.2 if (self.options.typeahead) { var typeahead = self.options.typeahead || {}; makeOptionFunction(typeahead, 'source'); self.$input.typeahead($.extend({}, typeahead, { source: function (query, process) { function processItems(items) { var texts = []; for (var i = 0; i < items.length; i++) { var text = self.options.itemText(items[i]); map[text] = items[i]; texts.push(text); } process(texts); } this.map = {}; var map = this.map, data = typeahead.source(query); if ($.isFunction(data.success)) { // support for Angular callbacks data.success(processItems); } else if ($.isFunction(data.then)) { // support for Angular promises data.then(processItems); } else { // support for functions and jquery promises $.when(data) .then(processItems); } }, updater: function (text) { self.add(this.map[text]); return this.map[text]; }, matcher: function (text) { return (text.toLowerCase().indexOf(this.query.trim().toLowerCase()) !== -1); }, sorter: function (texts) { return texts.sort(); }, highlighter: function (text) { var regex = new RegExp( '(' + this.query + ')', 'gi' ); return text.replace( regex, "<strong>$1</strong>" ); } })); } // typeahead.js if (self.options.typeaheadjs) { var typeaheadConfig = null; var typeaheadDatasets = {}; // Determine if main configurations were passed or simply a dataset var typeaheadjs = self.options.typeaheadjs; if ($.isArray(typeaheadjs)) { typeaheadConfig = typeaheadjs[0]; typeaheadDatasets = typeaheadjs[1]; } else { typeaheadDatasets = typeaheadjs; } self.$input.typeahead(typeaheadConfig, typeaheadDatasets).on('typeahead:selected', $.proxy(function (obj, datum) { if (typeaheadDatasets.valueKey) self.add(datum[typeaheadDatasets.valueKey]); else self.add(datum); self.$input.typeahead('val', ''); }, self)); } self.$container.on('click', $.proxy(function(event) { if (! self.$element.attr('disabled')) { self.$input.removeAttr('disabled'); } self.$input.focus(); }, self)); if (self.options.addOnBlur && self.options.freeInput) { self.$input.on('focusout', $.proxy(function(event) { // HACK: only process on focusout when no typeahead opened, to // avoid adding the typeahead text as tag if ($('.typeahead, .twitter-typeahead', self.$container).length === 0) { self.add(self.$input.val()); self.$input.val(''); } }, self)); } self.$container.on('keydown', 'input', $.proxy(function(event) { var $input = $(event.target), $inputWrapper = self.findInputWrapper(); if (self.$element.attr('disabled')) { self.$input.attr('disabled', 'disabled'); return; } switch (event.which) { // BACKSPACE case 8: if (doGetCaretPosition($input[0]) === 0) { var prev = $inputWrapper.prev(); if (prev.length) { self.remove(prev.data('item')); } } break; // DELETE case 46: if (doGetCaretPosition($input[0]) === 0) { var next = $inputWrapper.next(); if (next.length) { self.remove(next.data('item')); } } break; // LEFT ARROW case 37: // Try to move the input before the previous tag var $prevTag = $inputWrapper.prev(); if ($input.val().length === 0 && $prevTag[0]) { $prevTag.before($inputWrapper); $input.focus(); } break; // RIGHT ARROW case 39: // Try to move the input after the next tag var $nextTag = $inputWrapper.next(); if ($input.val().length === 0 && $nextTag[0]) { $nextTag.after($inputWrapper); $input.focus(); } break; default: // ignore } // Reset internal input's size var textLength = $input.val().length, wordSpace = Math.ceil(textLength / 5), size = textLength + wordSpace + 1; $input.attr('size', Math.max(this.inputSize, $input.val().length)); }, self)); self.$container.on('keypress', 'input', $.proxy(function(event) { var $input = $(event.target); if (self.$element.attr('disabled')) { self.$input.attr('disabled', 'disabled'); return; } var text = $input.val(), maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars; if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached)) { // Only attempt to add a tag if there is data in the field if (text.length !== 0) { self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text); $input.val(''); } // If the field is empty, let the event triggered fire as usual if (self.options.cancelConfirmKeysOnEmpty === false) { event.preventDefault(); } } // Reset internal input's size var textLength = $input.val().length, wordSpace = Math.ceil(textLength / 5), size = textLength + wordSpace + 1; $input.attr('size', Math.max(this.inputSize, $input.val().length)); }, self)); // Remove icon clicked self.$container.on('click', '[data-role=remove]', $.proxy(function(event) { if (self.$element.attr('disabled')) { return; } self.remove($(event.target).closest('.tag').data('item')); }, self)); // Only add existing value as tags when using strings as tags if (self.options.itemValue === defaultOptions.itemValue) { if (self.$element[0].tagName === 'INPUT') { self.add(self.$element.val()); } else { $('option', self.$element).each(function() { self.add($(this).attr('value'), true); }); } } }, /** * Removes all tagsinput behaviour and unregsiter all event handlers */ destroy: function() { var self = this; // Unbind events self.$container.off('keypress', 'input'); self.$container.off('click', '[role=remove]'); self.$container.remove(); self.$element.removeData('tagsinput'); self.$element.show(); }, /** * Sets focus on the tagsinput */ focus: function() { this.$input.focus(); }, /** * Returns the internal input element */ input: function() { return this.$input; }, /** * Returns the element which is wrapped around the internal input. This * is normally the $container, but typeahead.js moves the $input element. */ findInputWrapper: function() { var elt = this.$input[0], container = this.$container[0]; while(elt && elt.parentNode !== container) elt = elt.parentNode; return $(elt); } }; /** * Register JQuery plugin */ $.fn.tagsinput = function(arg1, arg2, arg3) { var results = []; this.each(function() { var tagsinput = $(this).data('tagsinput'); // Initialize a new tags input if (!tagsinput) { tagsinput = new TagsInput(this, arg1); $(this).data('tagsinput', tagsinput); results.push(tagsinput); if (this.tagName === 'SELECT') { $('option', $(this)).attr('selected', 'selected'); } // Init tags from $(this).val() $(this).val($(this).val()); } else if (!arg1 && !arg2) { // tagsinput already exists // no function, trying to init results.push(tagsinput); } else if(tagsinput[arg1] !== undefined) { // Invoke function on existing tags input if(tagsinput[arg1].length === 3 && arg3 !== undefined){ var retVal = tagsinput[arg1](arg2, null, arg3); }else{ var retVal = tagsinput[arg1](arg2); } if (retVal !== undefined) results.push(retVal); } }); if ( typeof arg1 == 'string') { // Return the results from the invoked function calls return results.length > 1 ? results : results[0]; } else { return results; } }; $.fn.tagsinput.Constructor = TagsInput; /** * Most options support both a string or number as well as a function as * option value. This function makes sure that the option with the given * key in the given options is wrapped in a function */ function makeOptionItemFunction(options, key) { if (typeof options[key] !== 'function') { var propertyName = options[key]; options[key] = function(item) { return item[propertyName]; }; } } function makeOptionFunction(options, key) { if (typeof options[key] !== 'function') { var value = options[key]; options[key] = function() { return value; }; } } /** * HtmlEncodes the given value */ var htmlEncodeContainer = $('<div />'); function htmlEncode(value) { if (value) { return htmlEncodeContainer.text(value).html(); } else { return ''; } } /** * Returns the position of the caret in the given input field * http://flightschool.acylt.com/devnotes/caret-position-woes/ */ function doGetCaretPosition(oField) { var iCaretPos = 0; if (document.selection) { oField.focus (); var oSel = document.selection.createRange(); oSel.moveStart ('character', -oField.value.length); iCaretPos = oSel.text.length; } else if (oField.selectionStart || oField.selectionStart == '0') { iCaretPos = oField.selectionStart; } return (iCaretPos); } /** * Returns boolean indicates whether user has pressed an expected key combination. * @param object keyPressEvent: JavaScript event object, refer * http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html * @param object lookupList: expected key combinations, as in: * [13, {which: 188, shiftKey: true}] */ function keyCombinationInList(keyPressEvent, lookupList) { var found = false; $.each(lookupList, function (index, keyCombination) { if (typeof (keyCombination) === 'number' && keyPressEvent.which === keyCombination) { found = true; return false; } if (keyPressEvent.which === keyCombination.which) { var alt = !keyCombination.hasOwnProperty('altKey') || keyPressEvent.altKey === keyCombination.altKey, shift = !keyCombination.hasOwnProperty('shiftKey') || keyPressEvent.shiftKey === keyCombination.shiftKey, ctrl = !keyCombination.hasOwnProperty('ctrlKey') || keyPressEvent.ctrlKey === keyCombination.ctrlKey; if (alt && shift && ctrl) { found = true; return false; } } }); return found; } /** * Initialize tagsinput behaviour on inputs and selects which have * data-role=tagsinput */ $(function() { $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput(); }); })(window.jQuery); dist/bootstrap-tagsinput.min.js000064400000021725151676724710012707 0ustar00/* * bootstrap-tagsinput v0.7.1 by Tim Schlechter * */ !function(a){"use strict";function b(b,c){this.isInit=!0,this.itemsArray=[],this.$element=a(b),this.$element.hide(),this.isSelect="SELECT"===b.tagName,this.multiple=this.isSelect&&b.hasAttribute("multiple"),this.objectItems=c&&c.itemValue,this.placeholderText=b.hasAttribute("placeholder")?this.$element.attr("placeholder"):"",this.inputSize=Math.max(1,this.placeholderText.length),this.$container=a('<div class="bootstrap-tagsinput"></div>'),this.$input=a('<input type="text" placeholder="'+this.placeholderText+'"/>').appendTo(this.$container),this.$element.before(this.$container),this.build(c),this.isInit=!1}function c(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(a){return a[c]}}}function d(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(){return c}}}function e(a){return a?i.text(a).html():""}function f(a){var b=0;if(document.selection){a.focus();var c=document.selection.createRange();c.moveStart("character",-a.value.length),b=c.text.length}else(a.selectionStart||"0"==a.selectionStart)&&(b=a.selectionStart);return b}function g(b,c){var d=!1;return a.each(c,function(a,c){if("number"==typeof c&&b.which===c)return d=!0,!1;if(b.which===c.which){var e=!c.hasOwnProperty("altKey")||b.altKey===c.altKey,f=!c.hasOwnProperty("shiftKey")||b.shiftKey===c.shiftKey,g=!c.hasOwnProperty("ctrlKey")||b.ctrlKey===c.ctrlKey;if(e&&f&&g)return d=!0,!1}}),d}var h={tagClass:function(a){return"label label-info"},itemValue:function(a){return a?a.toString():a},itemText:function(a){return this.itemValue(a)},itemTitle:function(a){return null},freeInput:!0,addOnBlur:!0,maxTags:void 0,maxChars:void 0,confirmKeys:[13,44],delimiter:",",delimiterRegex:null,cancelConfirmKeysOnEmpty:!1,onTagExists:function(a,b){b.hide().fadeIn()},trimValue:!1,allowDuplicates:!1};b.prototype={constructor:b,add:function(b,c,d){var f=this;if(!(f.options.maxTags&&f.itemsArray.length>=f.options.maxTags)&&(b===!1||b)){if("string"==typeof b&&f.options.trimValue&&(b=a.trim(b)),"object"==typeof b&&!f.objectItems)throw"Can't add objects when itemValue option is not set";if(!b.toString().match(/^\s*$/)){if(f.isSelect&&!f.multiple&&f.itemsArray.length>0&&f.remove(f.itemsArray[0]),"string"==typeof b&&"INPUT"===this.$element[0].tagName){var g=f.options.delimiterRegex?f.options.delimiterRegex:f.options.delimiter,h=b.split(g);if(h.length>1){for(var i=0;i<h.length;i++)this.add(h[i],!0);return void(c||f.pushVal())}}var j=f.options.itemValue(b),k=f.options.itemText(b),l=f.options.tagClass(b),m=f.options.itemTitle(b),n=a.grep(f.itemsArray,function(a){return f.options.itemValue(a)===j})[0];if(!n||f.options.allowDuplicates){if(!(f.items().toString().length+b.length+1>f.options.maxInputLength)){var o=a.Event("beforeItemAdd",{item:b,cancel:!1,options:d});if(f.$element.trigger(o),!o.cancel){f.itemsArray.push(b);var p=a('<span class="tag '+e(l)+(null!==m?'" title="'+m:"")+'">'+e(k)+'<span data-role="remove"></span></span>');p.data("item",b),f.findInputWrapper().before(p),p.after(" ");var q=a('option[value="'+encodeURIComponent(j)+'"]',f.$element).length||a('option[value="'+e(j)+'"]',f.$element).length;if(f.isSelect&&!q){var r=a("<option selected>"+e(k)+"</option>");r.data("item",b),r.attr("value",j),f.$element.append(r)}c||f.pushVal(),(f.options.maxTags===f.itemsArray.length||f.items().toString().length===f.options.maxInputLength)&&f.$container.addClass("bootstrap-tagsinput-max"),a(".typeahead, .twitter-typeahead",f.$container).length&&f.$input.typeahead("val",""),this.isInit?f.$element.trigger(a.Event("itemAddedOnInit",{item:b,options:d})):f.$element.trigger(a.Event("itemAdded",{item:b,options:d}))}}}else if(f.options.onTagExists){var s=a(".tag",f.$container).filter(function(){return a(this).data("item")===n});f.options.onTagExists(b,s)}}}},remove:function(b,c,d){var e=this;if(e.objectItems&&(b="object"==typeof b?a.grep(e.itemsArray,function(a){return e.options.itemValue(a)==e.options.itemValue(b)}):a.grep(e.itemsArray,function(a){return e.options.itemValue(a)==b}),b=b[b.length-1]),b){var f=a.Event("beforeItemRemove",{item:b,cancel:!1,options:d});if(e.$element.trigger(f),f.cancel)return;a(".tag",e.$container).filter(function(){return a(this).data("item")===b}).remove(),a("option",e.$element).filter(function(){return a(this).data("item")===b}).remove(),-1!==a.inArray(b,e.itemsArray)&&e.itemsArray.splice(a.inArray(b,e.itemsArray),1)}c||e.pushVal(),e.options.maxTags>e.itemsArray.length&&e.$container.removeClass("bootstrap-tagsinput-max"),e.$element.trigger(a.Event("itemRemoved",{item:b,options:d}))},removeAll:function(){var b=this;for(a(".tag",b.$container).remove(),a("option",b.$element).remove();b.itemsArray.length>0;)b.itemsArray.pop();b.pushVal()},refresh:function(){var b=this;a(".tag",b.$container).each(function(){var c=a(this),d=c.data("item"),f=b.options.itemValue(d),g=b.options.itemText(d),h=b.options.tagClass(d);if(c.attr("class",null),c.addClass("tag "+e(h)),c.contents().filter(function(){return 3==this.nodeType})[0].nodeValue=e(g),b.isSelect){var i=a("option",b.$element).filter(function(){return a(this).data("item")===d});i.attr("value",f)}})},items:function(){return this.itemsArray},pushVal:function(){var b=this,c=a.map(b.items(),function(a){return b.options.itemValue(a).toString()});b.$element.val(c,!0).trigger("change")},build:function(b){var e=this;if(e.options=a.extend({},h,b),e.objectItems&&(e.options.freeInput=!1),c(e.options,"itemValue"),c(e.options,"itemText"),d(e.options,"tagClass"),e.options.typeahead){var i=e.options.typeahead||{};d(i,"source"),e.$input.typeahead(a.extend({},i,{source:function(b,c){function d(a){for(var b=[],d=0;d<a.length;d++){var g=e.options.itemText(a[d]);f[g]=a[d],b.push(g)}c(b)}this.map={};var f=this.map,g=i.source(b);a.isFunction(g.success)?g.success(d):a.isFunction(g.then)?g.then(d):a.when(g).then(d)},updater:function(a){return e.add(this.map[a]),this.map[a]},matcher:function(a){return-1!==a.toLowerCase().indexOf(this.query.trim().toLowerCase())},sorter:function(a){return a.sort()},highlighter:function(a){var b=new RegExp("("+this.query+")","gi");return a.replace(b,"<strong>$1</strong>")}}))}if(e.options.typeaheadjs){var j=null,k={},l=e.options.typeaheadjs;a.isArray(l)?(j=l[0],k=l[1]):k=l,e.$input.typeahead(j,k).on("typeahead:selected",a.proxy(function(a,b){k.valueKey?e.add(b[k.valueKey]):e.add(b),e.$input.typeahead("val","")},e))}e.$container.on("click",a.proxy(function(a){e.$element.attr("disabled")||e.$input.removeAttr("disabled"),e.$input.focus()},e)),e.options.addOnBlur&&e.options.freeInput&&e.$input.on("focusout",a.proxy(function(b){0===a(".typeahead, .twitter-typeahead",e.$container).length&&(e.add(e.$input.val()),e.$input.val(""))},e)),e.$container.on("keydown","input",a.proxy(function(b){var c=a(b.target),d=e.findInputWrapper();if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");switch(b.which){case 8:if(0===f(c[0])){var g=d.prev();g.length&&e.remove(g.data("item"))}break;case 46:if(0===f(c[0])){var h=d.next();h.length&&e.remove(h.data("item"))}break;case 37:var i=d.prev();0===c.val().length&&i[0]&&(i.before(d),c.focus());break;case 39:var j=d.next();0===c.val().length&&j[0]&&(j.after(d),c.focus())}var k=c.val().length;Math.ceil(k/5);c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("keypress","input",a.proxy(function(b){var c=a(b.target);if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");var d=c.val(),f=e.options.maxChars&&d.length>=e.options.maxChars;e.options.freeInput&&(g(b,e.options.confirmKeys)||f)&&(0!==d.length&&(e.add(f?d.substr(0,e.options.maxChars):d),c.val("")),e.options.cancelConfirmKeysOnEmpty===!1&&b.preventDefault());var h=c.val().length;Math.ceil(h/5);c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("click","[data-role=remove]",a.proxy(function(b){e.$element.attr("disabled")||e.remove(a(b.target).closest(".tag").data("item"))},e)),e.options.itemValue===h.itemValue&&("INPUT"===e.$element[0].tagName?e.add(e.$element.val()):a("option",e.$element).each(function(){e.add(a(this).attr("value"),!0)}))},destroy:function(){var a=this;a.$container.off("keypress","input"),a.$container.off("click","[role=remove]"),a.$container.remove(),a.$element.removeData("tagsinput"),a.$element.show()},focus:function(){this.$input.focus()},input:function(){return this.$input},findInputWrapper:function(){for(var b=this.$input[0],c=this.$container[0];b&&b.parentNode!==c;)b=b.parentNode;return a(b)}},a.fn.tagsinput=function(c,d,e){var f=[];return this.each(function(){var g=a(this).data("tagsinput");if(g)if(c||d){if(void 0!==g[c]){if(3===g[c].length&&void 0!==e)var h=g[c](d,null,e);else var h=g[c](d);void 0!==h&&f.push(h)}}else f.push(g);else g=new b(this,c),a(this).data("tagsinput",g),f.push(g),"SELECT"===this.tagName&&a("option",a(this)).attr("selected","selected"),a(this).val(a(this).val())}),"string"==typeof c?f.length>1?f:f[0]:f},a.fn.tagsinput.Constructor=b;var i=a("<div />");a(function(){a("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput()})}(window.jQuery); //# sourceMappingURL=bootstrap-tagsinput.min.js.mapdist/bootstrap-tagsinput.min.js.map000064400000030003151676724710013450 0ustar00{"version":3,"sources":["../src/bootstrap-tagsinput.js"],"names":["$","TagsInput","element","options","this","isInit","itemsArray","$element","hide","isSelect","tagName","multiple","hasAttribute","objectItems","itemValue","placeholderText","attr","inputSize","Math","max","length","$container","$input","appendTo","before","build","makeOptionItemFunction","key","propertyName","item","makeOptionFunction","value","htmlEncode","htmlEncodeContainer","text","html","doGetCaretPosition","oField","iCaretPos","document","selection","focus","oSel","createRange","moveStart","selectionStart","keyCombinationInList","keyPressEvent","lookupList","found","each","index","keyCombination","which","alt","hasOwnProperty","altKey","shift","shiftKey","ctrl","ctrlKey","defaultOptions","tagClass","toString","itemText","itemTitle","freeInput","addOnBlur","maxTags","undefined","maxChars","confirmKeys","delimiter","delimiterRegex","cancelConfirmKeysOnEmpty","onTagExists","$tag","fadeIn","trimValue","allowDuplicates","prototype","constructor","add","dontPushVal","self","trim","match","remove","items","split","i","pushVal","existing","grep","maxInputLength","beforeItemAddEvent","Event","cancel","trigger","push","data","findInputWrapper","after","optionExists","encodeURIComponent","$option","append","addClass","typeahead","$existingTag","filter","other","beforeItemRemoveEvent","inArray","splice","removeClass","removeAll","pop","refresh","contents","nodeType","nodeValue","option","val","map","extend","source","query","process","processItems","texts","isFunction","success","then","when","updater","matcher","toLowerCase","indexOf","sorter","sort","highlighter","regex","RegExp","replace","typeaheadjs","typeaheadConfig","typeaheadDatasets","isArray","on","proxy","obj","datum","valueKey","event","removeAttr","target","$inputWrapper","prev","next","$prevTag","$nextTag","textLength","ceil","maxLengthReached","substr","preventDefault","closest","destroy","off","removeData","show","input","elt","container","parentNode","fn","tagsinput","arg1","arg2","arg3","results","retVal","Constructor","window","jQuery"],"mappings":"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","file":"bootstrap-tagsinput.min.js"}dist/bootstrap-tagsinput.less000064400000002004151676724710012444 0ustar00.bootstrap-tagsinput { background-color: #fff; border: 1px solid #ccc; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); display: inline-block; padding: 4px 6px; margin-bottom: 10px; color: #555; vertical-align: middle; border-radius: 4px; max-width: 100%; line-height: 22px; cursor: text; input { border: none; box-shadow: none; outline: none; background-color: transparent; padding: 0; margin: 0; width: auto !important; max-width: inherit; &:focus { border: none; box-shadow: none; } } .tag { margin-right: 2px; color: white; [data-role="remove"] { margin-left:8px; cursor:pointer; &:after{ content: "x"; padding:0px 2px; } &:hover { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); &:active { box-shadow: inset 0 3px 5px rgba(0,0,0,0.125); } } } } } dist/bootstrap-tagsinput.zip000064400000152250151676724710012311 0ustar00PK �jGdist/PK �jGv��gg#dist/bootstrap-tagsinput-angular.jsangular.module('bootstrap-tagsinput', []) .directive('bootstrapTagsinput', [function() { function getItemProperty(scope, property) { if (!property) return undefined; if (angular.isFunction(scope.$parent[property])) return scope.$parent[property]; return function(item) { return item[property]; }; } return { restrict: 'EA', scope: { model: '=ngModel' }, template: '<select multiple></select>', replace: false, link: function(scope, element, attrs) { $(function() { if (!angular.isArray(scope.model)) scope.model = []; var select = $('select', element); var typeaheadSourceArray = attrs.typeaheadSource ? attrs.typeaheadSource.split('.') : null; var typeaheadSource = typeaheadSourceArray ? (typeaheadSourceArray.length > 1 ? scope.$parent[typeaheadSourceArray[0]][typeaheadSourceArray[1]] : scope.$parent[typeaheadSourceArray[0]]) : null; select.tagsinput(scope.$parent[attrs.options || ''] || { typeahead : { source : angular.isFunction(typeaheadSource) ? typeaheadSource : null }, itemValue: getItemProperty(scope, attrs.itemvalue), itemText : getItemProperty(scope, attrs.itemtext), confirmKeys : getItemProperty(scope, attrs.confirmkeys) ? JSON.parse(attrs.confirmkeys) : [13], tagClass : angular.isFunction(scope.$parent[attrs.tagclass]) ? scope.$parent[attrs.tagclass] : function(item) { return attrs.tagclass; } }); for (var i = 0; i < scope.model.length; i++) { select.tagsinput('add', scope.model[i]); } select.on('itemAdded', function(event) { if (scope.model.indexOf(event.item) === -1) scope.model.push(event.item); }); select.on('itemRemoved', function(event) { var idx = scope.model.indexOf(event.item); if (idx !== -1) scope.model.splice(idx, 1); }); // create a shallow copy of model's current state, needed to determine // diff when model changes var prev = scope.model.slice(); scope.$watch("model", function() { var added = scope.model.filter(function(i) {return prev.indexOf(i) === -1;}), removed = prev.filter(function(i) {return scope.model.indexOf(i) === -1;}), i; prev = scope.model.slice(); // Remove tags no longer in binded model for (i = 0; i < removed.length; i++) { select.tagsinput('remove', removed[i]); } // Refresh remaining tags select.tagsinput('refresh'); // Add new items in model as tags for (i = 0; i < added.length; i++) { select.tagsinput('add', added[i]); } }, true); }); } }; }]); PK �jG�T+��'dist/bootstrap-tagsinput-angular.min.js/* * bootstrap-tagsinput v0.7.1 by Tim Schlechter * */ angular.module("bootstrap-tagsinput",[]).directive("bootstrapTagsinput",[function(){function a(a,b){return b?angular.isFunction(a.$parent[b])?a.$parent[b]:function(a){return a[b]}:void 0}return{restrict:"EA",scope:{model:"=ngModel"},template:"<select multiple></select>",replace:!1,link:function(b,c,d){$(function(){angular.isArray(b.model)||(b.model=[]);var e=$("select",c),f=d.typeaheadSource?d.typeaheadSource.split("."):null,g=f?f.length>1?b.$parent[f[0]][f[1]]:b.$parent[f[0]]:null;e.tagsinput(b.$parent[d.options||""]||{typeahead:{source:angular.isFunction(g)?g:null},itemValue:a(b,d.itemvalue),itemText:a(b,d.itemtext),confirmKeys:a(b,d.confirmkeys)?JSON.parse(d.confirmkeys):[13],tagClass:angular.isFunction(b.$parent[d.tagclass])?b.$parent[d.tagclass]:function(a){return d.tagclass}});for(var h=0;h<b.model.length;h++)e.tagsinput("add",b.model[h]);e.on("itemAdded",function(a){-1===b.model.indexOf(a.item)&&b.model.push(a.item)}),e.on("itemRemoved",function(a){var c=b.model.indexOf(a.item);-1!==c&&b.model.splice(c,1)});var i=b.model.slice();b.$watch("model",function(){var a,c=b.model.filter(function(a){return-1===i.indexOf(a)}),d=i.filter(function(a){return-1===b.model.indexOf(a)});for(i=b.model.slice(),a=0;a<d.length;a++)e.tagsinput("remove",d[a]);for(e.tagsinput("refresh"),a=0;a<c.length;a++)e.tagsinput("add",c[a])},!0)})}}}]); //# sourceMappingURL=bootstrap-tagsinput-angular.min.js.mapPK �jG �L�UUdist/bootstrap-tagsinput.js(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); }, itemTitle: function(item) { return null; }, freeInput: true, addOnBlur: true, maxTags: undefined, maxChars: undefined, confirmKeys: [13, 44], delimiter: ',', delimiterRegex: null, cancelConfirmKeysOnEmpty: false, onTagExists: function(item, $tag) { $tag.hide().fadeIn(); }, trimValue: false, allowDuplicates: false }; /** * Constructor function */ function TagsInput(element, options) { this.isInit = true; 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.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; this.inputSize = Math.max(1, this.placeholderText.length); this.$container = $('<div class="bootstrap-tagsinput"></div>'); this.$input = $('<input type="text" placeholder="' + this.placeholderText + '"/>').appendTo(this.$container); this.$element.before(this.$container); this.build(options); this.isInit = false; } TagsInput.prototype = { constructor: TagsInput, /** * Adds the given item as a new tag. Pass true to dontPushVal to prevent * updating the elements val() */ add: function(item, dontPushVal, options) { var self = this; if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) return; // Ignore falsey values, except false if (item !== false && !item) return; // Trim value if (typeof item === "string" && self.options.trimValue) { item = $.trim(item); } // 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 delimiter = (self.options.delimiterRegex) ? self.options.delimiterRegex : self.options.delimiter; var items = item.split(delimiter); if (items.length > 1) { for (var i = 0; i < items.length; i++) { this.add(items[i], true); } if (!dontPushVal) self.pushVal(); return; } } var itemValue = self.options.itemValue(item), itemText = self.options.itemText(item), tagClass = self.options.tagClass(item), itemTitle = self.options.itemTitle(item); // Ignore items allready added var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; if (existing && !self.options.allowDuplicates) { // Invoke onTagExists if (self.options.onTagExists) { var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); self.options.onTagExists(item, $existingTag); } return; } // if length greater than limit if (self.items().toString().length + item.length + 1 > self.options.maxInputLength) return; // raise beforeItemAdd arg var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options}); self.$element.trigger(beforeItemAddEvent); if (beforeItemAddEvent.cancel) return; // register item in internal array and map self.itemsArray.push(item); // add a tag element var $tag = $('<span class="tag ' + htmlEncode(tagClass) + (itemTitle !== null ? ('" title="' + itemTitle) : '') + '">' + htmlEncode(itemText) + '<span data-role="remove"></span></span>'); $tag.data('item', item); self.findInputWrapper().before($tag); $tag.after(' '); // Check to see if the tag exists in its raw or uri-encoded form var optionExists = ( $('option[value="' + encodeURIComponent(itemValue) + '"]', self.$element).length || $('option[value="' + htmlEncode(itemValue) + '"]', self.$element).length ); // add <option /> if item represents a value not present in one of the <select />'s options if (self.isSelect && !optionExists) { var $option = $('<option selected>' + htmlEncode(itemText) + '</option>'); $option.data('item', item); $option.attr('value', itemValue); self.$element.append($option); } if (!dontPushVal) self.pushVal(); // Add class when reached maxTags if (self.options.maxTags === self.itemsArray.length || self.items().toString().length === self.options.maxInputLength) self.$container.addClass('bootstrap-tagsinput-max'); // If using typeahead, once the tag has been added, clear the typeahead value so it does not stick around in the input. if ($('.typeahead, .twitter-typeahead', self.$container).length) { self.$input.typeahead('val', ''); } if (this.isInit) { self.$element.trigger($.Event('itemAddedOnInit', { item: item, options: options })); } else { self.$element.trigger($.Event('itemAdded', { item: item, options: options })); } }, /** * Removes the given item. Pass true to dontPushVal to prevent updating the * elements val() */ remove: function(item, dontPushVal, options) { var self = this; if (self.objectItems) { if (typeof item === "object") item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == self.options.itemValue(item); } ); else item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == item; } ); item = item[item.length-1]; } if (item) { var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false, options: options }); self.$element.trigger(beforeItemRemoveEvent); if (beforeItemRemoveEvent.cancel) return; $('.tag', self.$container).filter(function() { return $(this).data('item') === item; }).remove(); $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove(); if($.inArray(item, self.itemsArray) !== -1) self.itemsArray.splice($.inArray(item, self.itemsArray), 1); } if (!dontPushVal) self.pushVal(); // Remove class when reached maxTags if (self.options.maxTags > self.itemsArray.length) self.$container.removeClass('bootstrap-tagsinput-max'); self.$element.trigger($.Event('itemRemoved', { item: item, options: options })); }, /** * Removes all items */ removeAll: function() { var self = this; $('.tag', self.$container).remove(); $('option', self.$element).remove(); while(self.itemsArray.length > 0) self.itemsArray.pop(); self.pushVal(); }, /** * Refreshes the tags so they match the text/value of their corresponding * item. */ refresh: function() { var self = this; $('.tag', self.$container).each(function() { var $tag = $(this), item = $tag.data('item'), itemValue = self.options.itemValue(item), itemText = self.options.itemText(item), tagClass = self.options.tagClass(item); // Update tag's class and inner text $tag.attr('class', null); $tag.addClass('tag ' + htmlEncode(tagClass)); $tag.contents().filter(function() { return this.nodeType == 3; })[0].nodeValue = htmlEncode(itemText); if (self.isSelect) { var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; }); option.attr('value', itemValue); } }); }, /** * Returns the items added as tags */ items: function() { return this.itemsArray; }, /** * Assembly value by retrieving the value of each item, and set it on the * element. */ pushVal: function() { var self = this, val = $.map(self.items(), function(item) { return self.options.itemValue(item).toString(); }); self.$element.val(val, true).trigger('change'); }, /** * Initializes the tags input behaviour on the element */ build: function(options) { var self = this; self.options = $.extend({}, defaultOptions, options); // When itemValue is set, freeInput should always be false if (self.objectItems) self.options.freeInput = false; makeOptionItemFunction(self.options, 'itemValue'); makeOptionItemFunction(self.options, 'itemText'); makeOptionFunction(self.options, 'tagClass'); // Typeahead Bootstrap version 2.3.2 if (self.options.typeahead) { var typeahead = self.options.typeahead || {}; makeOptionFunction(typeahead, 'source'); self.$input.typeahead($.extend({}, typeahead, { source: function (query, process) { function processItems(items) { var texts = []; for (var i = 0; i < items.length; i++) { var text = self.options.itemText(items[i]); map[text] = items[i]; texts.push(text); } process(texts); } this.map = {}; var map = this.map, data = typeahead.source(query); if ($.isFunction(data.success)) { // support for Angular callbacks data.success(processItems); } else if ($.isFunction(data.then)) { // support for Angular promises data.then(processItems); } else { // support for functions and jquery promises $.when(data) .then(processItems); } }, updater: function (text) { self.add(this.map[text]); return this.map[text]; }, matcher: function (text) { return (text.toLowerCase().indexOf(this.query.trim().toLowerCase()) !== -1); }, sorter: function (texts) { return texts.sort(); }, highlighter: function (text) { var regex = new RegExp( '(' + this.query + ')', 'gi' ); return text.replace( regex, "<strong>$1</strong>" ); } })); } // typeahead.js if (self.options.typeaheadjs) { var typeaheadConfig = null; var typeaheadDatasets = {}; // Determine if main configurations were passed or simply a dataset var typeaheadjs = self.options.typeaheadjs; if ($.isArray(typeaheadjs)) { typeaheadConfig = typeaheadjs[0]; typeaheadDatasets = typeaheadjs[1]; } else { typeaheadDatasets = typeaheadjs; } self.$input.typeahead(typeaheadConfig, typeaheadDatasets).on('typeahead:selected', $.proxy(function (obj, datum) { if (typeaheadDatasets.valueKey) self.add(datum[typeaheadDatasets.valueKey]); else self.add(datum); self.$input.typeahead('val', ''); }, self)); } self.$container.on('click', $.proxy(function(event) { if (! self.$element.attr('disabled')) { self.$input.removeAttr('disabled'); } self.$input.focus(); }, self)); if (self.options.addOnBlur && self.options.freeInput) { self.$input.on('focusout', $.proxy(function(event) { // HACK: only process on focusout when no typeahead opened, to // avoid adding the typeahead text as tag if ($('.typeahead, .twitter-typeahead', self.$container).length === 0) { self.add(self.$input.val()); self.$input.val(''); } }, self)); } self.$container.on('keydown', 'input', $.proxy(function(event) { var $input = $(event.target), $inputWrapper = self.findInputWrapper(); if (self.$element.attr('disabled')) { self.$input.attr('disabled', 'disabled'); return; } switch (event.which) { // BACKSPACE case 8: if (doGetCaretPosition($input[0]) === 0) { var prev = $inputWrapper.prev(); if (prev.length) { self.remove(prev.data('item')); } } break; // DELETE case 46: if (doGetCaretPosition($input[0]) === 0) { var next = $inputWrapper.next(); if (next.length) { self.remove(next.data('item')); } } break; // LEFT ARROW case 37: // Try to move the input before the previous tag var $prevTag = $inputWrapper.prev(); if ($input.val().length === 0 && $prevTag[0]) { $prevTag.before($inputWrapper); $input.focus(); } break; // RIGHT ARROW case 39: // Try to move the input after the next tag var $nextTag = $inputWrapper.next(); if ($input.val().length === 0 && $nextTag[0]) { $nextTag.after($inputWrapper); $input.focus(); } break; default: // ignore } // Reset internal input's size var textLength = $input.val().length, wordSpace = Math.ceil(textLength / 5), size = textLength + wordSpace + 1; $input.attr('size', Math.max(this.inputSize, $input.val().length)); }, self)); self.$container.on('keypress', 'input', $.proxy(function(event) { var $input = $(event.target); if (self.$element.attr('disabled')) { self.$input.attr('disabled', 'disabled'); return; } var text = $input.val(), maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars; if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached)) { // Only attempt to add a tag if there is data in the field if (text.length !== 0) { self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text); $input.val(''); } // If the field is empty, let the event triggered fire as usual if (self.options.cancelConfirmKeysOnEmpty === false) { event.preventDefault(); } } // Reset internal input's size var textLength = $input.val().length, wordSpace = Math.ceil(textLength / 5), size = textLength + wordSpace + 1; $input.attr('size', Math.max(this.inputSize, $input.val().length)); }, self)); // Remove icon clicked self.$container.on('click', '[data-role=remove]', $.proxy(function(event) { if (self.$element.attr('disabled')) { return; } self.remove($(event.target).closest('.tag').data('item')); }, self)); // Only add existing value as tags when using strings as tags if (self.options.itemValue === defaultOptions.itemValue) { if (self.$element[0].tagName === 'INPUT') { self.add(self.$element.val()); } else { $('option', self.$element).each(function() { self.add($(this).attr('value'), true); }); } } }, /** * Removes all tagsinput behaviour and unregsiter all event handlers */ destroy: function() { var self = this; // Unbind events self.$container.off('keypress', 'input'); self.$container.off('click', '[role=remove]'); self.$container.remove(); self.$element.removeData('tagsinput'); self.$element.show(); }, /** * Sets focus on the tagsinput */ focus: function() { this.$input.focus(); }, /** * Returns the internal input element */ input: function() { return this.$input; }, /** * Returns the element which is wrapped around the internal input. This * is normally the $container, but typeahead.js moves the $input element. */ findInputWrapper: function() { var elt = this.$input[0], container = this.$container[0]; while(elt && elt.parentNode !== container) elt = elt.parentNode; return $(elt); } }; /** * Register JQuery plugin */ $.fn.tagsinput = function(arg1, arg2, arg3) { var results = []; this.each(function() { var tagsinput = $(this).data('tagsinput'); // Initialize a new tags input if (!tagsinput) { tagsinput = new TagsInput(this, arg1); $(this).data('tagsinput', tagsinput); results.push(tagsinput); if (this.tagName === 'SELECT') { $('option', $(this)).attr('selected', 'selected'); } // Init tags from $(this).val() $(this).val($(this).val()); } else if (!arg1 && !arg2) { // tagsinput already exists // no function, trying to init results.push(tagsinput); } else if(tagsinput[arg1] !== undefined) { // Invoke function on existing tags input if(tagsinput[arg1].length === 3 && arg3 !== undefined){ var retVal = tagsinput[arg1](arg2, null, arg3); }else{ var retVal = tagsinput[arg1](arg2); } if (retVal !== undefined) results.push(retVal); } }); if ( typeof arg1 == 'string') { // Return the results from the invoked function calls return results.length > 1 ? results : results[0]; } else { return results; } }; $.fn.tagsinput.Constructor = TagsInput; /** * Most options support both a string or number as well as a function as * option value. This function makes sure that the option with the given * key in the given options is wrapped in a function */ function makeOptionItemFunction(options, key) { if (typeof options[key] !== 'function') { var propertyName = options[key]; options[key] = function(item) { return item[propertyName]; }; } } function makeOptionFunction(options, key) { if (typeof options[key] !== 'function') { var value = options[key]; options[key] = function() { return value; }; } } /** * HtmlEncodes the given value */ var htmlEncodeContainer = $('<div />'); function htmlEncode(value) { if (value) { return htmlEncodeContainer.text(value).html(); } else { return ''; } } /** * Returns the position of the caret in the given input field * http://flightschool.acylt.com/devnotes/caret-position-woes/ */ function doGetCaretPosition(oField) { var iCaretPos = 0; if (document.selection) { oField.focus (); var oSel = document.selection.createRange(); oSel.moveStart ('character', -oField.value.length); iCaretPos = oSel.text.length; } else if (oField.selectionStart || oField.selectionStart == '0') { iCaretPos = oField.selectionStart; } return (iCaretPos); } /** * Returns boolean indicates whether user has pressed an expected key combination. * @param object keyPressEvent: JavaScript event object, refer * http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html * @param object lookupList: expected key combinations, as in: * [13, {which: 188, shiftKey: true}] */ function keyCombinationInList(keyPressEvent, lookupList) { var found = false; $.each(lookupList, function (index, keyCombination) { if (typeof (keyCombination) === 'number' && keyPressEvent.which === keyCombination) { found = true; return false; } if (keyPressEvent.which === keyCombination.which) { var alt = !keyCombination.hasOwnProperty('altKey') || keyPressEvent.altKey === keyCombination.altKey, shift = !keyCombination.hasOwnProperty('shiftKey') || keyPressEvent.shiftKey === keyCombination.shiftKey, ctrl = !keyCombination.hasOwnProperty('ctrlKey') || keyPressEvent.ctrlKey === keyCombination.ctrlKey; if (alt && shift && ctrl) { found = true; return false; } } }); return found; } /** * Initialize tagsinput behaviour on inputs and selects which have * data-role=tagsinput */ $(function() { $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput(); }); })(window.jQuery); PK �jG���#�#dist/bootstrap-tagsinput.min.js/* * bootstrap-tagsinput v0.7.1 by Tim Schlechter * */ !function(a){"use strict";function b(b,c){this.isInit=!0,this.itemsArray=[],this.$element=a(b),this.$element.hide(),this.isSelect="SELECT"===b.tagName,this.multiple=this.isSelect&&b.hasAttribute("multiple"),this.objectItems=c&&c.itemValue,this.placeholderText=b.hasAttribute("placeholder")?this.$element.attr("placeholder"):"",this.inputSize=Math.max(1,this.placeholderText.length),this.$container=a('<div class="bootstrap-tagsinput"></div>'),this.$input=a('<input type="text" placeholder="'+this.placeholderText+'"/>').appendTo(this.$container),this.$element.before(this.$container),this.build(c),this.isInit=!1}function c(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(a){return a[c]}}}function d(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(){return c}}}function e(a){return a?i.text(a).html():""}function f(a){var b=0;if(document.selection){a.focus();var c=document.selection.createRange();c.moveStart("character",-a.value.length),b=c.text.length}else(a.selectionStart||"0"==a.selectionStart)&&(b=a.selectionStart);return b}function g(b,c){var d=!1;return a.each(c,function(a,c){if("number"==typeof c&&b.which===c)return d=!0,!1;if(b.which===c.which){var e=!c.hasOwnProperty("altKey")||b.altKey===c.altKey,f=!c.hasOwnProperty("shiftKey")||b.shiftKey===c.shiftKey,g=!c.hasOwnProperty("ctrlKey")||b.ctrlKey===c.ctrlKey;if(e&&f&&g)return d=!0,!1}}),d}var h={tagClass:function(a){return"label label-info"},itemValue:function(a){return a?a.toString():a},itemText:function(a){return this.itemValue(a)},itemTitle:function(a){return null},freeInput:!0,addOnBlur:!0,maxTags:void 0,maxChars:void 0,confirmKeys:[13,44],delimiter:",",delimiterRegex:null,cancelConfirmKeysOnEmpty:!1,onTagExists:function(a,b){b.hide().fadeIn()},trimValue:!1,allowDuplicates:!1};b.prototype={constructor:b,add:function(b,c,d){var f=this;if(!(f.options.maxTags&&f.itemsArray.length>=f.options.maxTags)&&(b===!1||b)){if("string"==typeof b&&f.options.trimValue&&(b=a.trim(b)),"object"==typeof b&&!f.objectItems)throw"Can't add objects when itemValue option is not set";if(!b.toString().match(/^\s*$/)){if(f.isSelect&&!f.multiple&&f.itemsArray.length>0&&f.remove(f.itemsArray[0]),"string"==typeof b&&"INPUT"===this.$element[0].tagName){var g=f.options.delimiterRegex?f.options.delimiterRegex:f.options.delimiter,h=b.split(g);if(h.length>1){for(var i=0;i<h.length;i++)this.add(h[i],!0);return void(c||f.pushVal())}}var j=f.options.itemValue(b),k=f.options.itemText(b),l=f.options.tagClass(b),m=f.options.itemTitle(b),n=a.grep(f.itemsArray,function(a){return f.options.itemValue(a)===j})[0];if(!n||f.options.allowDuplicates){if(!(f.items().toString().length+b.length+1>f.options.maxInputLength)){var o=a.Event("beforeItemAdd",{item:b,cancel:!1,options:d});if(f.$element.trigger(o),!o.cancel){f.itemsArray.push(b);var p=a('<span class="tag '+e(l)+(null!==m?'" title="'+m:"")+'">'+e(k)+'<span data-role="remove"></span></span>');p.data("item",b),f.findInputWrapper().before(p),p.after(" ");var q=a('option[value="'+encodeURIComponent(j)+'"]',f.$element).length||a('option[value="'+e(j)+'"]',f.$element).length;if(f.isSelect&&!q){var r=a("<option selected>"+e(k)+"</option>");r.data("item",b),r.attr("value",j),f.$element.append(r)}c||f.pushVal(),(f.options.maxTags===f.itemsArray.length||f.items().toString().length===f.options.maxInputLength)&&f.$container.addClass("bootstrap-tagsinput-max"),a(".typeahead, .twitter-typeahead",f.$container).length&&f.$input.typeahead("val",""),this.isInit?f.$element.trigger(a.Event("itemAddedOnInit",{item:b,options:d})):f.$element.trigger(a.Event("itemAdded",{item:b,options:d}))}}}else if(f.options.onTagExists){var s=a(".tag",f.$container).filter(function(){return a(this).data("item")===n});f.options.onTagExists(b,s)}}}},remove:function(b,c,d){var e=this;if(e.objectItems&&(b="object"==typeof b?a.grep(e.itemsArray,function(a){return e.options.itemValue(a)==e.options.itemValue(b)}):a.grep(e.itemsArray,function(a){return e.options.itemValue(a)==b}),b=b[b.length-1]),b){var f=a.Event("beforeItemRemove",{item:b,cancel:!1,options:d});if(e.$element.trigger(f),f.cancel)return;a(".tag",e.$container).filter(function(){return a(this).data("item")===b}).remove(),a("option",e.$element).filter(function(){return a(this).data("item")===b}).remove(),-1!==a.inArray(b,e.itemsArray)&&e.itemsArray.splice(a.inArray(b,e.itemsArray),1)}c||e.pushVal(),e.options.maxTags>e.itemsArray.length&&e.$container.removeClass("bootstrap-tagsinput-max"),e.$element.trigger(a.Event("itemRemoved",{item:b,options:d}))},removeAll:function(){var b=this;for(a(".tag",b.$container).remove(),a("option",b.$element).remove();b.itemsArray.length>0;)b.itemsArray.pop();b.pushVal()},refresh:function(){var b=this;a(".tag",b.$container).each(function(){var c=a(this),d=c.data("item"),f=b.options.itemValue(d),g=b.options.itemText(d),h=b.options.tagClass(d);if(c.attr("class",null),c.addClass("tag "+e(h)),c.contents().filter(function(){return 3==this.nodeType})[0].nodeValue=e(g),b.isSelect){var i=a("option",b.$element).filter(function(){return a(this).data("item")===d});i.attr("value",f)}})},items:function(){return this.itemsArray},pushVal:function(){var b=this,c=a.map(b.items(),function(a){return b.options.itemValue(a).toString()});b.$element.val(c,!0).trigger("change")},build:function(b){var e=this;if(e.options=a.extend({},h,b),e.objectItems&&(e.options.freeInput=!1),c(e.options,"itemValue"),c(e.options,"itemText"),d(e.options,"tagClass"),e.options.typeahead){var i=e.options.typeahead||{};d(i,"source"),e.$input.typeahead(a.extend({},i,{source:function(b,c){function d(a){for(var b=[],d=0;d<a.length;d++){var g=e.options.itemText(a[d]);f[g]=a[d],b.push(g)}c(b)}this.map={};var f=this.map,g=i.source(b);a.isFunction(g.success)?g.success(d):a.isFunction(g.then)?g.then(d):a.when(g).then(d)},updater:function(a){return e.add(this.map[a]),this.map[a]},matcher:function(a){return-1!==a.toLowerCase().indexOf(this.query.trim().toLowerCase())},sorter:function(a){return a.sort()},highlighter:function(a){var b=new RegExp("("+this.query+")","gi");return a.replace(b,"<strong>$1</strong>")}}))}if(e.options.typeaheadjs){var j=null,k={},l=e.options.typeaheadjs;a.isArray(l)?(j=l[0],k=l[1]):k=l,e.$input.typeahead(j,k).on("typeahead:selected",a.proxy(function(a,b){k.valueKey?e.add(b[k.valueKey]):e.add(b),e.$input.typeahead("val","")},e))}e.$container.on("click",a.proxy(function(a){e.$element.attr("disabled")||e.$input.removeAttr("disabled"),e.$input.focus()},e)),e.options.addOnBlur&&e.options.freeInput&&e.$input.on("focusout",a.proxy(function(b){0===a(".typeahead, .twitter-typeahead",e.$container).length&&(e.add(e.$input.val()),e.$input.val(""))},e)),e.$container.on("keydown","input",a.proxy(function(b){var c=a(b.target),d=e.findInputWrapper();if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");switch(b.which){case 8:if(0===f(c[0])){var g=d.prev();g.length&&e.remove(g.data("item"))}break;case 46:if(0===f(c[0])){var h=d.next();h.length&&e.remove(h.data("item"))}break;case 37:var i=d.prev();0===c.val().length&&i[0]&&(i.before(d),c.focus());break;case 39:var j=d.next();0===c.val().length&&j[0]&&(j.after(d),c.focus())}var k=c.val().length;Math.ceil(k/5);c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("keypress","input",a.proxy(function(b){var c=a(b.target);if(e.$element.attr("disabled"))return void e.$input.attr("disabled","disabled");var d=c.val(),f=e.options.maxChars&&d.length>=e.options.maxChars;e.options.freeInput&&(g(b,e.options.confirmKeys)||f)&&(0!==d.length&&(e.add(f?d.substr(0,e.options.maxChars):d),c.val("")),e.options.cancelConfirmKeysOnEmpty===!1&&b.preventDefault());var h=c.val().length;Math.ceil(h/5);c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("click","[data-role=remove]",a.proxy(function(b){e.$element.attr("disabled")||e.remove(a(b.target).closest(".tag").data("item"))},e)),e.options.itemValue===h.itemValue&&("INPUT"===e.$element[0].tagName?e.add(e.$element.val()):a("option",e.$element).each(function(){e.add(a(this).attr("value"),!0)}))},destroy:function(){var a=this;a.$container.off("keypress","input"),a.$container.off("click","[role=remove]"),a.$container.remove(),a.$element.removeData("tagsinput"),a.$element.show()},focus:function(){this.$input.focus()},input:function(){return this.$input},findInputWrapper:function(){for(var b=this.$input[0],c=this.$container[0];b&&b.parentNode!==c;)b=b.parentNode;return a(b)}},a.fn.tagsinput=function(c,d,e){var f=[];return this.each(function(){var g=a(this).data("tagsinput");if(g)if(c||d){if(void 0!==g[c]){if(3===g[c].length&&void 0!==e)var h=g[c](d,null,e);else var h=g[c](d);void 0!==h&&f.push(h)}}else f.push(g);else g=new b(this,c),a(this).data("tagsinput",g),f.push(g),"SELECT"===this.tagName&&a("option",a(this)).attr("selected","selected"),a(this).val(a(this).val())}),"string"==typeof c?f.length>1?f:f[0]:f},a.fn.tagsinput.Constructor=b;var i=a("<div />");a(function(){a("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput()})}(window.jQuery); //# sourceMappingURL=bootstrap-tagsinput.min.js.mapPK �jG�����&dist/bootstrap-tagsinput-typeahead.css.twitter-typeahead .tt-query, .twitter-typeahead .tt-hint { margin-bottom: 0; } .twitter-typeahead .tt-hint { display: none; } .tt-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; list-style: none; font-size: 14px; background-color: #ffffff; border: 1px solid #cccccc; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 4px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); background-clip: padding-box; cursor: pointer; } .tt-suggestion { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.428571429; color: #333333; white-space: nowrap; } .tt-suggestion:hover, .tt-suggestion:focus { color: #ffffff; text-decoration: none; outline: 0; background-color: #428bca; } PK �jGi��6%%dist/bootstrap-tagsinput.css.bootstrap-tagsinput { background-color: #fff; border: 1px solid #ccc; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); display: inline-block; padding: 4px 6px; color: #555; vertical-align: middle; border-radius: 4px; max-width: 100%; line-height: 22px; cursor: text; } .bootstrap-tagsinput input { border: none; box-shadow: none; outline: none; background-color: transparent; padding: 0 6px; margin: 0; width: auto; max-width: inherit; } .bootstrap-tagsinput.form-control input::-moz-placeholder { color: #777; opacity: 1; } .bootstrap-tagsinput.form-control input:-ms-input-placeholder { color: #777; } .bootstrap-tagsinput.form-control input::-webkit-input-placeholder { color: #777; } .bootstrap-tagsinput input:focus { border: none; box-shadow: none; } .bootstrap-tagsinput .tag { margin-right: 2px; color: white; } .bootstrap-tagsinput .tag [data-role="remove"] { margin-left: 8px; cursor: pointer; } .bootstrap-tagsinput .tag [data-role="remove"]:after { content: "x"; padding: 0px 2px; } .bootstrap-tagsinput .tag [data-role="remove"]:hover { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } .bootstrap-tagsinput .tag [data-role="remove"]:hover:active { box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } PK �jG�lN���dist/bootstrap-tagsinput.less.bootstrap-tagsinput { background-color: #fff; border: 1px solid #ccc; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); display: inline-block; padding: 4px 6px; margin-bottom: 10px; color: #555; vertical-align: middle; border-radius: 4px; max-width: 100%; line-height: 22px; cursor: text; input { border: none; box-shadow: none; outline: none; background-color: transparent; padding: 0; margin: 0; width: auto !important; max-width: inherit; &:focus { border: none; box-shadow: none; } } .tag { margin-right: 2px; color: white; [data-role="remove"] { margin-left:8px; cursor:pointer; &:after{ content: "x"; padding:0px 2px; } &:hover { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); &:active { box-shadow: inset 0 3px 5px rgba(0,0,0,0.125); } } } } } PK �jGPS�oo+dist/bootstrap-tagsinput-angular.min.js.map{"version":3,"sources":["../src/bootstrap-tagsinput-angular.js"],"names":["angular","module","directive","getItemProperty","scope","property","isFunction","$parent","item","undefined","restrict","model","template","replace","link","element","attrs","$","isArray","select","typeaheadSourceArray","typeaheadSource","split","length","tagsinput","options","typeahead","source","itemValue","itemvalue","itemText","itemtext","confirmKeys","confirmkeys","JSON","parse","tagClass","tagclass","i","on","event","indexOf","push","idx","splice","prev","slice","$watch","added","filter","removed"],"mappings":";;;;;AAAAA,QAAQC,OAAO,0BACdC,UAAU,sBAAuB,WAEhC,QAASC,GAAgBC,EAAOC,GAC9B,MAAKA,GAGDL,QAAQM,WAAWF,EAAMG,QAAQF,IAC5BD,EAAMG,QAAQF,GAEhB,SAASG,GACd,MAAOA,GAAKH,IANLI,OAUX,OACEC,SAAU,KACVN,OACEO,MAAO,YAETC,SAAU,6BACVC,SAAS,EACTC,KAAM,SAASV,EAAOW,EAASC,GAC7BC,EAAE,WACKjB,QAAQkB,QAAQd,EAAMO,SACzBP,EAAMO,SAER,IAAIQ,GAASF,EAAE,SAAUF,GACrBK,EAAuBJ,EAAMK,gBAAkBL,EAAMK,gBAAgBC,MAAM,KAAO,KAClFD,EAAkBD,EACjBA,EAAqBG,OAAS,EAC3BnB,EAAMG,QAAQa,EAAqB,IAAIA,EAAqB,IAC1DhB,EAAMG,QAAQa,EAAqB,IACvC,IAEND,GAAOK,UAAUpB,EAAMG,QAAQS,EAAMS,SAAW,MAC9CC,WACEC,OAAW3B,QAAQM,WAAWe,GAAmBA,EAAkB,MAErEO,UAAWzB,EAAgBC,EAAOY,EAAMa,WACxCC,SAAW3B,EAAgBC,EAAOY,EAAMe,UACxCC,YAAc7B,EAAgBC,EAAOY,EAAMiB,aAAeC,KAAKC,MAAMnB,EAAMiB,cAAgB,IAC3FG,SAAWpC,QAAQM,WAAWF,EAAMG,QAAQS,EAAMqB,WAAajC,EAAMG,QAAQS,EAAMqB,UAAY,SAAS7B,GAAQ,MAAOQ,GAAMqB,WAG/H,KAAK,GAAIC,GAAI,EAAGA,EAAIlC,EAAMO,MAAMY,OAAQe,IACtCnB,EAAOK,UAAU,MAAOpB,EAAMO,MAAM2B,GAGtCnB,GAAOoB,GAAG,YAAa,SAASC,GACU,KAApCpC,EAAMO,MAAM8B,QAAQD,EAAMhC,OAC5BJ,EAAMO,MAAM+B,KAAKF,EAAMhC,QAG3BW,EAAOoB,GAAG,cAAe,SAASC,GAChC,GAAIG,GAAMvC,EAAMO,MAAM8B,QAAQD,EAAMhC,KACxB,MAARmC,GACFvC,EAAMO,MAAMiC,OAAOD,EAAK,IAK5B,IAAIE,GAAOzC,EAAMO,MAAMmC,OACvB1C,GAAM2C,OAAO,QAAS,WACpB,GAEIT,GAFAU,EAAQ5C,EAAMO,MAAMsC,OAAO,SAASX,GAAI,MAA2B,KAApBO,EAAKJ,QAAQH,KAC5DY,EAAUL,EAAKI,OAAO,SAASX,GAAI,MAAkC,KAA3BlC,EAAMO,MAAM8B,QAAQH,IAMlE,KAHAO,EAAOzC,EAAMO,MAAMmC,QAGdR,EAAI,EAAGA,EAAIY,EAAQ3B,OAAQe,IAC9BnB,EAAOK,UAAU,SAAU0B,EAAQZ,GAOrC,KAHAnB,EAAOK,UAAU,WAGZc,EAAI,EAAGA,EAAIU,EAAMzB,OAAQe,IAC5BnB,EAAOK,UAAU,MAAOwB,EAAMV,MAE/B","file":"bootstrap-tagsinput-angular.min.js"}PK �jG��R,00#dist/bootstrap-tagsinput.min.js.map{"version":3,"sources":["../src/bootstrap-tagsinput.js"],"names":["$","TagsInput","element","options","this","isInit","itemsArray","$element","hide","isSelect","tagName","multiple","hasAttribute","objectItems","itemValue","placeholderText","attr","inputSize","Math","max","length","$container","$input","appendTo","before","build","makeOptionItemFunction","key","propertyName","item","makeOptionFunction","value","htmlEncode","htmlEncodeContainer","text","html","doGetCaretPosition","oField","iCaretPos","document","selection","focus","oSel","createRange","moveStart","selectionStart","keyCombinationInList","keyPressEvent","lookupList","found","each","index","keyCombination","which","alt","hasOwnProperty","altKey","shift","shiftKey","ctrl","ctrlKey","defaultOptions","tagClass","toString","itemText","itemTitle","freeInput","addOnBlur","maxTags","undefined","maxChars","confirmKeys","delimiter","delimiterRegex","cancelConfirmKeysOnEmpty","onTagExists","$tag","fadeIn","trimValue","allowDuplicates","prototype","constructor","add","dontPushVal","self","trim","match","remove","items","split","i","pushVal","existing","grep","maxInputLength","beforeItemAddEvent","Event","cancel","trigger","push","data","findInputWrapper","after","optionExists","encodeURIComponent","$option","append","addClass","typeahead","$existingTag","filter","other","beforeItemRemoveEvent","inArray","splice","removeClass","removeAll","pop","refresh","contents","nodeType","nodeValue","option","val","map","extend","source","query","process","processItems","texts","isFunction","success","then","when","updater","matcher","toLowerCase","indexOf","sorter","sort","highlighter","regex","RegExp","replace","typeaheadjs","typeaheadConfig","typeaheadDatasets","isArray","on","proxy","obj","datum","valueKey","event","removeAttr","target","$inputWrapper","prev","next","$prevTag","$nextTag","textLength","ceil","maxLengthReached","substr","preventDefault","closest","destroy","off","removeData","show","input","elt","container","parentNode","fn","tagsinput","arg1","arg2","arg3","results","retVal","Constructor","window","jQuery"],"mappings":"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","file":"bootstrap-tagsinput.min.js"}PK �jGdist/PK �jGv��gg##dist/bootstrap-tagsinput-angular.jsPK �jG�T+��'�dist/bootstrap-tagsinput-angular.min.jsPK �jG �L�UU�dist/bootstrap-tagsinput.jsPK �jG���#�# gdist/bootstrap-tagsinput.min.jsPK �jG�����&�dist/bootstrap-tagsinput-typeahead.cssPK �jGi��6%%(�dist/bootstrap-tagsinput.cssPK �jG�lN�����dist/bootstrap-tagsinput.lessPK �jGPS�oo+��dist/bootstrap-tagsinput-angular.min.js.mapPK �jG��R,00#L�dist/bootstrap-tagsinput.min.js.mapPK ��dist/bootstrap-tagsinput-angular.js000064400000005676151676724710013563 0ustar00angular.module('bootstrap-tagsinput', []) .directive('bootstrapTagsinput', [function() { function getItemProperty(scope, property) { if (!property) return undefined; if (angular.isFunction(scope.$parent[property])) return scope.$parent[property]; return function(item) { return item[property]; }; } return { restrict: 'EA', scope: { model: '=ngModel' }, template: '<select multiple></select>', replace: false, link: function(scope, element, attrs) { $(function() { if (!angular.isArray(scope.model)) scope.model = []; var select = $('select', element); var typeaheadSourceArray = attrs.typeaheadSource ? attrs.typeaheadSource.split('.') : null; var typeaheadSource = typeaheadSourceArray ? (typeaheadSourceArray.length > 1 ? scope.$parent[typeaheadSourceArray[0]][typeaheadSourceArray[1]] : scope.$parent[typeaheadSourceArray[0]]) : null; select.tagsinput(scope.$parent[attrs.options || ''] || { typeahead : { source : angular.isFunction(typeaheadSource) ? typeaheadSource : null }, itemValue: getItemProperty(scope, attrs.itemvalue), itemText : getItemProperty(scope, attrs.itemtext), confirmKeys : getItemProperty(scope, attrs.confirmkeys) ? JSON.parse(attrs.confirmkeys) : [13], tagClass : angular.isFunction(scope.$parent[attrs.tagclass]) ? scope.$parent[attrs.tagclass] : function(item) { return attrs.tagclass; } }); for (var i = 0; i < scope.model.length; i++) { select.tagsinput('add', scope.model[i]); } select.on('itemAdded', function(event) { if (scope.model.indexOf(event.item) === -1) scope.model.push(event.item); }); select.on('itemRemoved', function(event) { var idx = scope.model.indexOf(event.item); if (idx !== -1) scope.model.splice(idx, 1); }); // create a shallow copy of model's current state, needed to determine // diff when model changes var prev = scope.model.slice(); scope.$watch("model", function() { var added = scope.model.filter(function(i) {return prev.indexOf(i) === -1;}), removed = prev.filter(function(i) {return scope.model.indexOf(i) === -1;}), i; prev = scope.model.slice(); // Remove tags no longer in binded model for (i = 0; i < removed.length; i++) { select.tagsinput('remove', removed[i]); } // Refresh remaining tags select.tagsinput('refresh'); // Add new items in model as tags for (i = 0; i < added.length; i++) { select.tagsinput('add', added[i]); } }, true); }); } }; }]); dist/bootstrap-tagsinput-typeahead.css000064400000002000151676724710014224 0ustar00.twitter-typeahead .tt-query, .twitter-typeahead .tt-hint { margin-bottom: 0; } .twitter-typeahead .tt-hint { display: none; } .tt-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; list-style: none; font-size: 14px; background-color: #ffffff; border: 1px solid #cccccc; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 4px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); background-clip: padding-box; cursor: pointer; } .tt-suggestion { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.428571429; color: #333333; white-space: nowrap; } .tt-suggestion:hover, .tt-suggestion:focus { color: #ffffff; text-decoration: none; outline: 0; background-color: #428bca; } dist/bootstrap-tagsinput.css000064400000002534151676724710012276 0ustar00.bootstrap-tagsinput { background-color: #fff; border: 1px solid #ccc; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); display: inline-block; padding: 4px 6px; color: #555; vertical-align: middle; border-radius: 4px; max-width: 100%; line-height: 22px; cursor: text; } .bootstrap-tagsinput input { border: none; box-shadow: none; outline: none; background-color: transparent; padding: 0 6px; margin: 0; width: auto; max-width: inherit; } .bootstrap-tagsinput.form-control input::-moz-placeholder { color: #777; opacity: 1; } .bootstrap-tagsinput.form-control input:-ms-input-placeholder { color: #777; } .bootstrap-tagsinput.form-control input::-webkit-input-placeholder { color: #777; } .bootstrap-tagsinput input:focus { border: none; box-shadow: none; } .bootstrap-tagsinput .tag { margin-right: 2px; color: white; } .bootstrap-tagsinput .tag [data-role="remove"] { margin-left: 8px; cursor: pointer; } .bootstrap-tagsinput .tag [data-role="remove"]:after { content: "x"; padding: 0px 2px; } .bootstrap-tagsinput .tag [data-role="remove"]:hover { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); } .bootstrap-tagsinput .tag [data-role="remove"]:hover:active { box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } dist/bootstrap-tagsinput-angular.min.js.map000064400000004157151676724710015112 0ustar00{"version":3,"sources":["../src/bootstrap-tagsinput-angular.js"],"names":["angular","module","directive","getItemProperty","scope","property","isFunction","$parent","item","undefined","restrict","model","template","replace","link","element","attrs","$","isArray","select","typeaheadSourceArray","typeaheadSource","split","length","tagsinput","options","typeahead","source","itemValue","itemvalue","itemText","itemtext","confirmKeys","confirmkeys","JSON","parse","tagClass","tagclass","i","on","event","indexOf","push","idx","splice","prev","slice","$watch","added","filter","removed"],"mappings":";;;;;AAAAA,QAAQC,OAAO,0BACdC,UAAU,sBAAuB,WAEhC,QAASC,GAAgBC,EAAOC,GAC9B,MAAKA,GAGDL,QAAQM,WAAWF,EAAMG,QAAQF,IAC5BD,EAAMG,QAAQF,GAEhB,SAASG,GACd,MAAOA,GAAKH,IANLI,OAUX,OACEC,SAAU,KACVN,OACEO,MAAO,YAETC,SAAU,6BACVC,SAAS,EACTC,KAAM,SAASV,EAAOW,EAASC,GAC7BC,EAAE,WACKjB,QAAQkB,QAAQd,EAAMO,SACzBP,EAAMO,SAER,IAAIQ,GAASF,EAAE,SAAUF,GACrBK,EAAuBJ,EAAMK,gBAAkBL,EAAMK,gBAAgBC,MAAM,KAAO,KAClFD,EAAkBD,EACjBA,EAAqBG,OAAS,EAC3BnB,EAAMG,QAAQa,EAAqB,IAAIA,EAAqB,IAC1DhB,EAAMG,QAAQa,EAAqB,IACvC,IAEND,GAAOK,UAAUpB,EAAMG,QAAQS,EAAMS,SAAW,MAC9CC,WACEC,OAAW3B,QAAQM,WAAWe,GAAmBA,EAAkB,MAErEO,UAAWzB,EAAgBC,EAAOY,EAAMa,WACxCC,SAAW3B,EAAgBC,EAAOY,EAAMe,UACxCC,YAAc7B,EAAgBC,EAAOY,EAAMiB,aAAeC,KAAKC,MAAMnB,EAAMiB,cAAgB,IAC3FG,SAAWpC,QAAQM,WAAWF,EAAMG,QAAQS,EAAMqB,WAAajC,EAAMG,QAAQS,EAAMqB,UAAY,SAAS7B,GAAQ,MAAOQ,GAAMqB,WAG/H,KAAK,GAAIC,GAAI,EAAGA,EAAIlC,EAAMO,MAAMY,OAAQe,IACtCnB,EAAOK,UAAU,MAAOpB,EAAMO,MAAM2B,GAGtCnB,GAAOoB,GAAG,YAAa,SAASC,GACU,KAApCpC,EAAMO,MAAM8B,QAAQD,EAAMhC,OAC5BJ,EAAMO,MAAM+B,KAAKF,EAAMhC,QAG3BW,EAAOoB,GAAG,cAAe,SAASC,GAChC,GAAIG,GAAMvC,EAAMO,MAAM8B,QAAQD,EAAMhC,KACxB,MAARmC,GACFvC,EAAMO,MAAMiC,OAAOD,EAAK,IAK5B,IAAIE,GAAOzC,EAAMO,MAAMmC,OACvB1C,GAAM2C,OAAO,QAAS,WACpB,GAEIT,GAFAU,EAAQ5C,EAAMO,MAAMsC,OAAO,SAASX,GAAI,MAA2B,KAApBO,EAAKJ,QAAQH,KAC5DY,EAAUL,EAAKI,OAAO,SAASX,GAAI,MAAkC,KAA3BlC,EAAMO,MAAM8B,QAAQH,IAMlE,KAHAO,EAAOzC,EAAMO,MAAMmC,QAGdR,EAAI,EAAGA,EAAIY,EAAQ3B,OAAQe,IAC9BnB,EAAOK,UAAU,SAAU0B,EAAQZ,GAOrC,KAHAnB,EAAOK,UAAU,WAGZc,EAAI,EAAGA,EAAIU,EAAMzB,OAAQe,IAC5BnB,EAAOK,UAAU,MAAOwB,EAAMV,MAE/B","file":"bootstrap-tagsinput-angular.min.js"}dist/bootstrap-tagsinput-angular.min.js000064400000002700151676724710014326 0ustar00/* * bootstrap-tagsinput v0.7.1 by Tim Schlechter * */ angular.module("bootstrap-tagsinput",[]).directive("bootstrapTagsinput",[function(){function a(a,b){return b?angular.isFunction(a.$parent[b])?a.$parent[b]:function(a){return a[b]}:void 0}return{restrict:"EA",scope:{model:"=ngModel"},template:"<select multiple></select>",replace:!1,link:function(b,c,d){$(function(){angular.isArray(b.model)||(b.model=[]);var e=$("select",c),f=d.typeaheadSource?d.typeaheadSource.split("."):null,g=f?f.length>1?b.$parent[f[0]][f[1]]:b.$parent[f[0]]:null;e.tagsinput(b.$parent[d.options||""]||{typeahead:{source:angular.isFunction(g)?g:null},itemValue:a(b,d.itemvalue),itemText:a(b,d.itemtext),confirmKeys:a(b,d.confirmkeys)?JSON.parse(d.confirmkeys):[13],tagClass:angular.isFunction(b.$parent[d.tagclass])?b.$parent[d.tagclass]:function(a){return d.tagclass}});for(var h=0;h<b.model.length;h++)e.tagsinput("add",b.model[h]);e.on("itemAdded",function(a){-1===b.model.indexOf(a.item)&&b.model.push(a.item)}),e.on("itemRemoved",function(a){var c=b.model.indexOf(a.item);-1!==c&&b.model.splice(c,1)});var i=b.model.slice();b.$watch("model",function(){var a,c=b.model.filter(function(a){return-1===i.indexOf(a)}),d=i.filter(function(a){return-1===b.model.indexOf(a)});for(i=b.model.slice(),a=0;a<d.length;a++)e.tagsinput("remove",d[a]);for(e.tagsinput("refresh"),a=0;a<c.length;a++)e.tagsinput("add",c[a])},!0)})}}}]); //# sourceMappingURL=bootstrap-tagsinput-angular.min.js.map.npmignore000064400000000150151676724710006557 0ustar00node_modules/ bower_components/ lib/ examples/local.html examples/issue.html examples/index2.html examples/assets/citynames.json000064400000000340151676724710012570 0ustar00[ "Amsterdam", "London", "Paris", "Washington", "New York", "Los Angeles", "Sydney", "Melbourne", "Canberra", "Beijing", "New Delhi", "Kathmandu", "Cairo", "Cape Town", "Kinshasa" ]examples/assets/app_bs3.js000064400000005477151676724710011606 0ustar00var citynames = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: { url: 'assets/citynames.json', filter: function(list) { return $.map(list, function(cityname) { return { name: cityname }; }); } } }); citynames.initialize(); var cities = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('text'), queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: 'assets/cities.json' }); cities.initialize(); /** * Typeahead */ var elt = $('.example_typeahead > > input'); elt.tagsinput({ typeaheadjs: { name: 'citynames', displayKey: 'name', valueKey: 'name', source: citynames.ttAdapter() } }); /** * Objects as tags */ elt = $('.example_objects_as_tags > > input'); elt.tagsinput({ itemValue: 'value', itemText: 'text', typeaheadjs: { name: 'cities', displayKey: 'text', source: cities.ttAdapter() } }); elt.tagsinput('add', { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }); elt.tagsinput('add', { "value": 4 , "text": "Washington" , "continent": "America" }); elt.tagsinput('add', { "value": 7 , "text": "Sydney" , "continent": "Australia" }); elt.tagsinput('add', { "value": 10, "text": "Beijing" , "continent": "Asia" }); elt.tagsinput('add', { "value": 13, "text": "Cairo" , "continent": "Africa" }); /** * Categorizing tags */ elt = $('.example_tagclass > > input'); elt.tagsinput({ tagClass: function(item) { switch (item.continent) { case 'Europe' : return 'label label-primary'; case 'America' : return 'label label-danger label-important'; case 'Australia': return 'label label-success'; case 'Africa' : return 'label label-default'; case 'Asia' : return 'label label-warning'; } }, itemValue: 'value', itemText: 'text', // typeaheadjs: { // name: 'cities', // displayKey: 'text', // source: cities.ttAdapter() // } typeaheadjs: [ { hint: true, highlight: true, minLength: 2 }, { name: 'cities', displayKey: 'text', source: cities.ttAdapter() } ] }); elt.tagsinput('add', { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }); elt.tagsinput('add', { "value": 4 , "text": "Washington" , "continent": "America" }); elt.tagsinput('add', { "value": 7 , "text": "Sydney" , "continent": "Australia" }); elt.tagsinput('add', { "value": 10, "text": "Beijing" , "continent": "Asia" }); elt.tagsinput('add', { "value": 13, "text": "Cairo" , "continent": "Africa" }); // HACK: overrule hardcoded display inline-block of typeahead.js $(".twitter-typeahead").css('display', 'inline'); examples/assets/app.css000064400000002363151676724710011202 0ustar00.icon-github { background: no-repeat url('../img/github-16px.png'); width: 16px; height: 16px; } .bootstrap-tagsinput { width: 100%; } .accordion { margin-bottom:-3px; } .accordion-group { border: none; } .twitter-typeahead .tt-query, .twitter-typeahead .tt-hint { margin-bottom: 0; } .twitter-typeahead .tt-hint { display: none; } .tt-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; list-style: none; font-size: 14px; background-color: #ffffff; border: 1px solid #cccccc; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 4px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); background-clip: padding-box; cursor: pointer; } .tt-suggestion { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.428571429; color: #333333; white-space: nowrap; } .tt-suggestion:hover, .tt-suggestion:focus { color: #ffffff; text-decoration: none; outline: 0; background-color: #428bca; } examples/assets/app.js000064400000001033151676724710011017 0ustar00$(function() { $('input, select').on('change', function(event) { var $element = $(event.target), $container = $element.closest('.example'); if (!$element.data('tagsinput')) return; var val = $element.val(); if (val === null) val = "null"; $('code', $('pre.val', $container)).html( ($.isArray(val) ? JSON.stringify(val) : "\"" + val.replace('"', '\\"') + "\"") ); $('code', $('pre.items', $container)).html(JSON.stringify($element.tagsinput('items'))); }).trigger('change'); });examples/assets/cities.json000064400000002032151676724710012054 0ustar00[ { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }, { "value": 2 , "text": "London" , "continent": "Europe" }, { "value": 3 , "text": "Paris" , "continent": "Europe" }, { "value": 4 , "text": "Washington" , "continent": "America" }, { "value": 5 , "text": "Mexico City" , "continent": "America" }, { "value": 6 , "text": "Buenos Aires", "continent": "America" }, { "value": 7 , "text": "Sydney" , "continent": "Australia" }, { "value": 8 , "text": "Wellington" , "continent": "Australia" }, { "value": 9 , "text": "Canberra" , "continent": "Australia" }, { "value": 10, "text": "Beijing" , "continent": "Asia" }, { "value": 11, "text": "New Delhi" , "continent": "Asia" }, { "value": 12, "text": "Kathmandu" , "continent": "Asia" }, { "value": 13, "text": "Cairo" , "continent": "Africa" }, { "value": 14, "text": "Cape Town" , "continent": "Africa" }, { "value": 15, "text": "Kinshasa" , "continent": "Africa" } ]examples/assets/app_bs2.js000064400000006300151676724710011567 0ustar00$('.example_typeahead > > input').tagsinput({ typeahead: { source: function(query) { return $.getJSON('assets/citynames.json'); } } }); $('.example_objects_as_tags > > input').tagsinput({ itemValue: 'value', itemText: 'text', typeahead: { source: function(query) { return $.getJSON('assets/cities.json'); } } }); $('.example_objects_as_tags > > input').tagsinput('add', { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }); $('.example_objects_as_tags > > input').tagsinput('add', { "value": 4 , "text": "Washington" , "continent": "America" }); $('.example_objects_as_tags > > input').tagsinput('add', { "value": 7 , "text": "Sydney" , "continent": "Australia" }); $('.example_objects_as_tags > > input').tagsinput('add', { "value": 10, "text": "Beijing" , "continent": "Asia" }); $('.example_objects_as_tags > > input').tagsinput('add', { "value": 13, "text": "Cairo" , "continent": "Africa" }); $('.example_tagclass > > input').tagsinput({ tagClass: function(item) { switch (item.continent) { case 'Europe' : return 'label label-info'; case 'America' : return 'label label-danger label-important'; case 'Australia': return 'label label-success'; case 'Africa' : return 'label'; case 'Asia' : return 'label label-warning'; } }, itemValue: 'value', itemText: 'text', typeahead: { source: function(query) { return $.getJSON('assets/cities.json'); } } }); $('.example_tagclass > > input').tagsinput('add', { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }); $('.example_tagclass > > input').tagsinput('add', { "value": 4 , "text": "Washington" , "continent": "America" }); $('.example_tagclass > > input').tagsinput('add', { "value": 7 , "text": "Sydney" , "continent": "Australia" }); $('.example_tagclass > > input').tagsinput('add', { "value": 10, "text": "Beijing" , "continent": "Asia" }); $('.example_tagclass > > input').tagsinput('add', { "value": 13, "text": "Cairo" , "continent": "Africa" }); angular.module('AngularExample', ['bootstrap-tagsinput']) .controller('CityTagsInputController', function CityTagsInputController($scope, $http) { // Init with some cities $scope.cities = [ { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }, { "value": 4 , "text": "Washington" , "continent": "America" }, { "value": 7 , "text": "Sydney" , "continent": "Australia" }, { "value": 10, "text": "Beijing" , "continent": "Asia" }, { "value": 13, "text": "Cairo" , "continent": "Africa" } ]; $scope.queryCities = function(query) { return $http.get('assets/cities.json'); }; $scope.getTagClass = function(city) { switch (city.continent) { case 'Europe' : return 'label label-info'; case 'America' : return 'label label-danger label-important'; case 'Australia': return 'label label-success'; case 'Africa' : return 'label'; case 'Asia' : return 'label label-warning'; } }; } );examples/bootstrap-2.3.2.html000064400000072062151676724710011754 0ustar00<!DOCTYPE html> <html> <head> <title>Bootstrap Tags Input</title> <meta name="robots" content="index, follow" /> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css"> <link rel="stylesheet" href="../dist/bootstrap-tagsinput.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/themes/github.css"> <link rel="stylesheet" href="http://getbootstrap.com/2.3.2/assets/css/docs.css"> <link rel="stylesheet" href="assets/app.css"> <style> .accordion { margin-top:-19px; } </style> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-42755476-1', 'timschlechter.github.io'); ga('send', 'pageview'); </script> </head> <body> <div id="fb-root"></div> <div class="navbar navbar-inverse navbar-fixed-top bs-docs-nav"> <div class="navbar-inner"> <div class="container"> <div class="nav-collapse collapse bs-navbar-collapse"> <ul class="nav navbar-nav"> <li> <a href="https://github.com/timschlechter/bootstrap-tagsinput">Code on Github</a> </li> <li> <a href=".">Bootstrap 3</a> </li> <li> <a href="http://timschlechter.github.io/bootstrap-tagsinput/dist/bootstrap-tagsinput.zip">Download <small>(latest)</small></a> </li> </ul> <p class="navbar-text pull-right"> <a href="https://twitter.com/share" class="navbar-link twitter-share-button" data-hashtags="bootstraptagsinput">Tweet</a> <script>!function (d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (!d.getElementById(id)) { js = d.createElement(s); js.id = id; js.src = "//platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs); } }(document, "script", "twitter-wjs");</script> <!-- Place this tag where you want the +1 button to render. --> <a class="navbar-link g-plusone" data-size="medium"></a> <!-- Place this tag after the last +1 button tag. --> <script type="text/javascript"> (function () { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })(); </script> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/all.js#xfbml=1&appId=122064240555"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> <a class="navbar-link fb-like" data-href="http://timschlechter.github.io/bootstrap-tagsinput/examples/" data-width="110" data-layout="button_count" data-show-faces="true" data-send="false"></a> </p> </div> </div> </div> </div> <header class="jumbotron subhead"> <div class="container"> <h1>Bootstrap Tags Input</h1> <p>jQuery plugin providing a Twitter Bootstrap user interface for managing tags</p> </header> <div class="container"> <section id="examples"> <div class="page-header"> <h2>Examples</h2> </div> <div class="example example_markup"> <h3>Markup</h3> <p> Just add <code>data-role="tagsinput"</code> to your input field to automatically change it to a tags input field. </p> <div class="bs-docs-example"> <input type="text" value="Amsterdam,Washington,Sydney,Beijing,Cairo" data-role="tagsinput" placeholder="Add tags" /> </div> <div class="accordion"> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#accordion_example_markup"> Show code </a> </div> <div id="accordion_example_markup" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><input type="text" value="Amsterdam,Washington,Sydney,Beijing,Cairo" data-role="tagsinput" placeholder="Add tags" /></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("input").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("input").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <div class="example example_multivalue"> <h3>True multi value</h3> <p> Use a <code><select multiple /></code> as your input element for a tags input, to gain true multivalue support. Instead of a comma separated string, the values will be set in an array. Existing <code><option /></code> elements will automatically be set as tags. This makes it also possible to create tags containing a comma. </p> <div class="bs-docs-example"> <select multiple data-role="tagsinput"> <option value="Amsterdam">Amsterdam</option> <option value="Washington">Washington</option> <option value="Sydney">Sydney</option> <option value="Beijing">Beijing</option> <option value="Cairo">Cairo</option> </select> </div> <div class="accordion "> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#example_multivalue"> Show code </a> </div> <div id="example_multivalue" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><select multiple data-role="tagsinput"> <option value="Amsterdam">Amsterdam</option> <option value="Washington">Washington</option> <option value="Sydney">Sydney</option> <option value="Beijing">Beijing</option> <option value="Cairo">Cairo</option> </select></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("select").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("select").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <div class="example example_typeahead"> <h3>Typeahead</h3> <div class="bs-docs-example"> <input type="text" value="Amsterdam,Washington" /> </div> <div class="accordion "> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse"href="#example_typeahead"> Show code </a> </div> <div id="example_typeahead" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><input type="text" value="Amsterdam,Washington" data-role="tagsinput" /> <script> $('input').tagsinput({ typeahead: { source: function(query) { return $.getJSON('citynames.json'); } } }); </script></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("input").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("input").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <div class="example example_objects_as_tags"> <h3>Objects as tags</h3> <p> Instead of just adding strings as tags, bind objects to your tags. This makes it possible to set id values in your input field's value, instead of just the tag's text. </p> <div class="bs-docs-example"> <input type="text" /> </div> <div class="accordion"> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#accordion_example_objects_as_tags"> Show code </a> </div> <div id="accordion_example_objects_as_tags" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><input type="text" /> <script> $('input').tagsinput({ itemValue: 'value', itemText: 'text', typeahead: { source: function(query) { return $.getJSON('cities.json'); } } }); $('input').tagsinput('add', { "value": 1 , "text": "Amsterdam" }); $('input').tagsinput('add', { "value": 4 , "text": "Washington" }); $('input').tagsinput('add', { "value": 7 , "text": "Sydney" }); $('input').tagsinput('add', { "value": 10, "text": "Beijing" }); $('input').tagsinput('add', { "value": 13, "text": "Cairo" }); </script></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("input").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("input").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <div class="example example_tagclass"> <h3>Categorizing tags</h3> <p> You can set a fixed css class for your tags, or determine dynamically by providing a custom function. </p> <div class="bs-docs-example"> <input type="text" /> </div> <div class="accordion"> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#accordion_example_tagclass"> Show code </a> </div> <div id="accordion_example_tagclass" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><input type="text" /> <script> $('input').tagsinput({ tagClass: function(item) { switch (item.continent) { case 'Europe' : return 'label label-info'; case 'America' : return 'label label-important'; case 'Australia': return 'label label-success'; case 'Africa' : return 'badge badge-inverse'; case 'Asia' : return 'badge badge-warning'; } }, itemValue: 'value', itemText: 'text', typeahead: { source: function(query) { return $.getJSON('cities.json'); } } }); $('input').tagsinput('add', { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }); $('input').tagsinput('add', { "value": 4 , "text": "Washington" , "continent": "America" }); $('input').tagsinput('add', { "value": 7 , "text": "Sydney" , "continent": "Australia" }); $('input').tagsinput('add', { "value": 10, "text": "Beijing" , "continent": "Asia" }); $('input').tagsinput('add', { "value": 13, "text": "Cairo" , "continent": "Africa" }); </script></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("input").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("input").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <div id="angular" class="example example_angular" ng-app="AngularExample" ng-controller="CityTagsInputController"> <h3>AngularJS support</h3> <p> Include <code>bootstrap-tagsinput-angular.js</code> and register the 'bootstrap-tagsinput' in your Angular JS application to use the bootstrap-tagsinput directive. </p> <div class="bs-docs-example"> <bootstrap-tagsinput ng-model="cities" typeahead-source="queryCities" tagclass="getTagClass" itemvalue="value" itemtext="text"> </bootstrap-tagsinput> </div> <div class="accordion"> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#example_angular"> Show code </a> </div> <div id="example_angular" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><bootstrap-tagsinput ng-model="cities" typeahead-source="queryCities" tagclass="getTagClass" itemvalue="value" itemtext="text"> </bootstrap-tagsinput> <script> angular.module('AngularExample', ['bootstrap-tagsinput']) .controller('CityTagsInputController', function CityTagsInputController($scope) { // Init with some cities $scope.cities = [ { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }, { "value": 4 , "text": "Washington" , "continent": "America" }, { "value": 7 , "text": "Sydney" , "continent": "Australia" }, { "value": 10, "text": "Beijing" , "continent": "Asia" }, { "value": 13, "text": "Cairo" , "continent": "Africa" } ]; $scope.queryCities = function(query) { return $http.get('cities.json'); }; $scope.getTagClass = function(city) { switch (city.continent) { case 'Europe' : return 'badge badge-info'; case 'America' : return 'label label-important'; case 'Australia': return 'badge badge-success'; case 'Africa' : return 'label label-inverse'; case 'Asia' : return 'badge badge-warning'; } }; } ); </script></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"> <thead> <tr><th>statement</th><th>returns</th></tr> </thead> <tbody> <tr><td><code>$scope.cities</code></td><td><pre><code data-language="javascript">{{cities}}</code></pre></td></tr> <tr><td><code>$("select").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr> <tr><td><code>$("select").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr> </tbody> </table> </div> </section> <section id="options"> <div class="page-header"> <h2>Options</h2> </div> <table class="table table-bordered table-condensed"> <thead> <tr> <th colspan="2">option</th> <th>description</th> </tr> </thead> <tbody> <tr> <td colspan="2"><code>tagClass</code></td> <td> <p>Classname for the tags, or a function returning a classname</p> <pre><code data-language="javascript">$('input').tagsinput({ tagClass: 'big' });</code></pre> <pre><code data-language="javascript">$('input').tagsinput({ tagClass: function(item) { return (item.length > 10 ? 'big' : 'small'); } });</code></pre> </td> </tr> <tr> <td colspan="2"><code>itemValue</code></td> <td> <p>When adding objects as tags, itemValue <em>must</em> be set to the name of the property containing the item's value, or a function returning an item's value.</p> <pre><code data-language="javascript">$('input').tagsinput({ itemValue: 'id' });</code></pre> <pre><code data-language="javascript">$('input').tagsinput({ itemValue: function(item) { return item.id; } });</code></pre> </td> </tr> <tr> <td colspan="2"><code>itemText</code></td> <td> <p>When adding objects as tags, you can set itemText to the name of the property of item to use for a its tag's text. You may also provide a function which returns an item's value. When this options is not set, the value of <code>itemValue</code> will be used. <pre><code data-language="javascript">$('input').tagsinput({ itemText: 'label' });</code></pre> <pre><code data-language="javascript">$('input').tagsinput({ itemText: function(item) { return item.label; } });</code></pre> </td> </tr> <tr> <td colspan="2"><code>confirmKeys</code></td> <td> <p>Array of keycodes which will add a tag when typing in the input. (default: [13, 188], which are ENTER and comma)</p> <pre><code data-language="javascript">$('input').tagsinput({ confirmKeys: [13, 44] });</code></pre> </td> </tr> <tr> <td colspan="2"><code>maxTags</code></td> <td> <p>When set, no more than the given number of tags are allowed to add (default: undefined). When maxTags is reached, a class 'bootstrap-tagsinput-max' is placed on the tagsinput element. (default: undefined)</p> <pre><code data-language="javascript">$('input').tagsinput({ maxTags: 3 });</code></pre> </td> </tr> <tr> <td colspan="2"><code>maxChars</code></td> <td> <p>Defines the maximum length of a single tag. (default: undefined)</p> <pre><code data-language="javascript">$('input').tagsinput({ maxChars: 8 });</code></pre> </td> </tr> <tr> <td colspan="2"><code>trimValue</code></td> <td> <p>When true, automatically removes all whitespace around tags. (default: false)</p> <pre><code data-language="javascript">$('input').tagsinput({ trimValue: true });</code></pre> </td> </tr> <tr> <td colspan="2"><code>allowDuplicates</code></td> <td> <p>When true, the same tag can be added multiple times. (default: false)</p> <pre><code data-language="javascript">$('input').tagsinput({ allowDuplicates: true });</code></pre> </td> </tr> <tr> <td colspan="2"><code>maxChars</code></td> <td> <p>Defines the maximum length of a single tag.</p> <pre><code data-language="javascript">$('input').tagsinput({ maxChars: 8 });</code></pre> </td> </tr> <tr> <td colspan="2"><code>freeInput</code></td> <td> <p>Allow creating tags which are not returned by typeahead's source (default: true)</p> <div class="alert alert-block"> This is only possible when using string as tags. When itemValue option is set, this option will be ignored. </div> <pre><code data-language="javascript">$('input').tagsinput({ typeahead: { source: ['Amsterdam', 'Washington', 'Sydney', 'Beijing', 'Cairo'], freeInput: true } });</code></pre> </td> </tr> <tr> <td colspan="2"><code>typeahead</code></td> <td><p>Object containing typeahead specific options</td> </tr> </tr> <tr> <td></td> <td><code>source</code></td> <td> <p>An array (or function returning a promise or array), which will be used as source for a typeahead. <pre><code data-language="javascript">$('input').tagsinput({ typeahead: { source: ['Amsterdam', 'Washington', 'Sydney', 'Beijing', 'Cairo'] } });</code></pre> <pre><code data-language="javascript">$('input').tagsinput({ typeahead: { source: function(query) { return $.get('http://someservice.com'); } } });</code></pre> </td> </tr> <tr> <td colspan="2"><code>onTagExists</code></td> <td><p>Function invoked when trying to add an item which allready exists. By default, the existing tag hides and fades in. <pre><code data-language="javascript">$('input').tagsinput({ onTagExists: function(item, $tag) { $tag.hide.fadeIn(); } });</code></pre> </td> </tr> </tbody> </table> </section> <section id="methods"> <div class="page-header"> <h2>Methods</h2> </div> <table class="table table-bordered table-condensed"> <thead> <tr> <th>method</th> <th>description</th> </tr> </thead> <tbody> <tr> <td><code>add</code></td> <td> <p>Adds a tag</p> <pre><code data-language="javascript">$('input').tagsinput('add', 'some tag');</code></pre> <pre><code data-language="javascript">$('input').tagsinput('add', { id: 1, text: 'some tag' });</code></pre> </td> </tr> <tr> <td><code>remove</code></td> <td> <p>Removes a tag</p> <pre><code data-language="javascript">$('input').tagsinput('remove', 'some tag');</code></pre> <pre><code data-language="javascript">$('input').tagsinput('remove', { id: 1, text: 'some tag' });</code></pre> </td> </tr> <tr> <td><code>removeAll</code></td> <td> <p>Removes all tags</p> <pre><code data-language="javascript">$('input').tagsinput('removeAll');</code></pre> </td> </tr> <tr> <td><code>focus</code></td> <td> <p>Sets focus in the tagsinput</p> <pre><code data-language="javascript">$('input').tagsinput('focus');</code></pre> </td> </tr> <tr> <td><code>input</code></td> <td> <p>Returns the tagsinput's internal <input />, which is used for adding tags. You could use this to add your own typeahead behaviour for example.</p> <pre><code data-language="html">var $elt = $('input').tagsinput('input');</code></pre> </td> </tr> <tr> <td><code>refresh</code></td> <td> <p>Refreshes the tags input UI. This might be usefull when you're adding objects as tags. When an object's text changes, you'll have to refresh to update the matching tag's text.</p> <pre><code data-language="javascript">$('input').tagsinput('refresh');</code></pre> </td> </tr> <tr> <td><code>destroy</code></td> <td> <p>Removes tagsinput behaviour</p> <pre><code data-language="javascript">$('input').tagsinput('destroy');</code></pre> </td> </tr> </tbody> </table> </section> <section id="methods"> <div class="page-header"> <h2>Events</h2> </div> <table class="table table-bordered table-condensed"> <thead> <tr> <th>event</th> <th>description</th> </tr> </thead> <tbody> <tr> <td><code>beforeItemAdd</code></td> <td> Triggered just before an item gets added. Example: <pre><code data-language="javascript">$('input').on('beforeItemAdd', function(event) { // event.item: contains the item // event.cancel: set to true to prevent the item getting added });</code></pre> </td> </tr> <tr> <td><code>itemAdded</code></td> <td> Triggered just after an item got added. Example: <pre><code data-language="javascript">$('input').on('itemAdded', function(event) { // event.item: contains the item });</code></pre> </td> </tr> <tr> <td><code>beforeItemRemove</code></td> <td> Triggered just before an item gets removed. Example: <pre><code data-language="javascript">$('input').on('beforeItemRemove', function(event) { // event.item: contains the item // event.cancel: set to true to prevent the item getting removed });</code></pre> </td> </tr> <tr> <td><code>itemRemoved</code></td> <td> Triggered just after an item got removed. Example: <pre><code data-language="javascript">$('input').on('itemRemoved', function(event) { // event.item: contains the item });</code></pre> </td> </tr> </tbody> </table> </section> </div> <footer class="footer"> <p>Code licensed under <a href="https://raw.github.com/TimSchlechter/bootstrap-tagsinput/master/LICENSE" target="_blank">MIT License</a></p> </footer> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script> <script src="../dist/bootstrap-tagsinput.min.js"></script> <script src="../dist/bootstrap-tagsinput/bootstrap-tagsinput-angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/js/rainbow.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/js/language/generic.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/js/language/html.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/js/language/javascript.js"></script> <script src="assets/app_bs2.js"></script> <script src="assets/app.js"></script> </body> </html> examples/index.html000064400000100122151676724710010373 0ustar00<!DOCTYPE html> <html> <head> <title>Bootstrap Tags Input</title> <meta name="robots" content="index, follow" /> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap-theme.min.css"> <link rel="stylesheet" href="../dist/bootstrap-tagsinput.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/themes/github.css"> <link rel="stylesheet" href="assets/app.css"> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-42755476-1', 'bootstrap-tagsinput.github.io'); ga('send', 'pageview'); </script> </head> <body> <div id="fb-root"></div> <div class="jumbotron"> <div class="container"> <h1>Bootstrap Tags Input</h1> <p>jQuery plugin providing a Twitter Bootstrap user interface for managing tags</p> <p> <a class="btn btn-default" role="button" href="https://github.com/bootstrap-tagsinput/bootstrap-tagsinput">Code on Github</a> <a class="btn btn-default" role="button" href="bootstrap-2.3.2.html">Bootstrap 2.3.2</a> <a class="btn btn-primary" role="button" href="https://codeload.github.com/bootstrap-tagsinput/bootstrap-tagsinput/zip/latest">Download</a> </p> <p> <ul class="list-inline"> <li> <iframe src="//ghbtns.com/github-btn.html?user=bootstrap-tagsinput&repo=bootstrap-tagsinput&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20"></iframe> </li> <li> <iframe src="//ghbtns.com/github-btn.html?user=bootstrap-tagsinput&repo=bootstrap-tagsinput&type=fork&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20"></iframe> </li> <li> <a href="https://twitter.com/share" class="navbar-link twitter-share-button" data-hashtags="bootstraptagsinput">Tweet</a> <script>!function (d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (!d.getElementById(id)) { js = d.createElement(s); js.id = id; js.src = "//platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs); } }(document, "script", "twitter-wjs");</script> </li> <li> <a class="navbar-link g-plusone" data-size="medium"></a> <script type="text/javascript"> (function () { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })(); </script> </li> </ul> </p> </div> </div> <div class="container"> <section id="examples"> <div class="page-header"> <h2>Examples</h2> </div> <div class="example example_markup"> <h3>Markup</h3> <p>Just add <code>data-role="tagsinput"</code> to your input field to automatically change it to a tags input field.</p> <div class="bs-example"> <input type="text" value="Amsterdam,Washington,Sydney,Beijing,Cairo" data-role="tagsinput" /> </div> <div class="accordion"> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#accordion_example_markup"> Show code </a> </div> <div id="accordion_example_markup" class="accordion-body collapse"> <div class="accordion-inner highlight"> <pre><code data-language="html"><input type="text" value="Amsterdam,Washington,Sydney,Beijing,Cairo" data-role="tagsinput" /></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("input").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("input").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <div class="example example_multivalue"> <h3>True multi value</h3> <p> Use a <code><select multiple /></code> as your input element for a tags input, to gain true multivalue support. Instead of a comma separated string, the values will be set in an array. Existing <code><option /></code> elements will automatically be set as tags. This makes it also possible to create tags containing a comma. </p> <div class="bs-example"> <select multiple data-role="tagsinput"> <option value="Amsterdam">Amsterdam</option> <option value="Washington">Washington</option> <option value="Sydney">Sydney</option> <option value="Beijing">Beijing</option> <option value="Cairo">Cairo</option> </select> </div> <div class="accordion "> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#example_multivalue"> Show code </a> </div> <div id="example_multivalue" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><select multiple data-role="tagsinput"> <option value="Amsterdam">Amsterdam</option> <option value="Washington">Washington</option> <option value="Sydney">Sydney</option> <option value="Beijing">Beijing</option> <option value="Cairo">Cairo</option> </select></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("select").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("select").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <div class="example example_typeahead"> <h3>Typeahead</h3> Typeahead is not included in Bootstrap 3, so you'll have to include your own typeahead library. I'd recommed <a href="http://twitter.github.io/typeahead.js/">typeahead.js</a>. An example of using this is shown below. <div class="bs-example"> <input type="text" value="Amsterdam,Washington" /> </div> <div class="accordion "> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse"href="#example_typeahead"> Show code </a> </div> <div id="example_typeahead" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><input type="text" value="Amsterdam,Washington" data-role="tagsinput" /> <script> var citynames = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: { url: 'assets/citynames.json', filter: function(list) { return $.map(list, function(cityname) { return { name: cityname }; }); } } }); citynames.initialize(); $('input').tagsinput({ typeaheadjs: { name: 'citynames', displayKey: 'name', valueKey: 'name', source: citynames.ttAdapter() } }); </script></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("input").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("input").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <div class="example example_objects_as_tags"> <h3>Objects as tags</h3> <p> Instead of just adding strings as tags, bind objects to your tags. This makes it possible to set id values in your input field's value, instead of just the tag's text. </p> <div class="bs-example"> <input type="text" /> </div> <div class="accordion"> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#accordion_example_objects_as_tags"> Show code </a> </div> <div id="accordion_example_objects_as_tags" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><input type="text" /> <script> var cities = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('text'), queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: 'assets/cities.json' }); cities.initialize(); var elt = $('input'); elt.tagsinput({ itemValue: 'value', itemText: 'text', typeaheadjs: { name: 'cities', displayKey: 'text', source: cities.ttAdapter() } }); elt.tagsinput('add', { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }); elt.tagsinput('add', { "value": 4 , "text": "Washington" , "continent": "America" }); elt.tagsinput('add', { "value": 7 , "text": "Sydney" , "continent": "Australia" }); elt.tagsinput('add', { "value": 10, "text": "Beijing" , "continent": "Asia" }); elt.tagsinput('add', { "value": 13, "text": "Cairo" , "continent": "Africa" }); </script></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("input").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("input").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <div class="example example_tagclass"> <h3>Categorizing tags</h3> <p> You can set a fixed css class for your tags, or determine dynamically by providing a custom function. </p> <div class="bs-example"> <input type="text" /> </div> <div class="accordion"> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#accordion_example_tagclass"> Show code </a> </div> <div id="accordion_example_tagclass" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><input type="text" /> <script> var cities = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('text'), queryTokenizer: Bloodhound.tokenizers.whitespace, prefetch: 'assets/cities.json' }); cities.initialize(); var elt = $('input'); elt.tagsinput({ tagClass: function(item) { switch (item.continent) { case 'Europe' : return 'label label-primary'; case 'America' : return 'label label-danger label-important'; case 'Australia': return 'label label-success'; case 'Africa' : return 'label label-default'; case 'Asia' : return 'label label-warning'; } }, itemValue: 'value', itemText: 'text', typeaheadjs: { name: 'cities', displayKey: 'text', source: cities.ttAdapter() } }); elt.tagsinput('add', { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }); elt.tagsinput('add', { "value": 4 , "text": "Washington" , "continent": "America" }); elt.tagsinput('add', { "value": 7 , "text": "Sydney" , "continent": "Australia" }); elt.tagsinput('add', { "value": 10, "text": "Beijing" , "continent": "Asia" }); elt.tagsinput('add', { "value": 13, "text": "Cairo" , "continent": "Africa" }); </script></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"><thead><tr><th>statement</th><th>returns</th></tr></thead><tbody><tr><td><code>$("input").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr><tr><td><code>$("input").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr></tbody></table> </div> <!-- div id="angular" class="example example_angular" ng-app="AngularExample" ng-controller="CityTagsInputController"> <h3>AngularJS support</h3> <p> Include <code>bootstrap-tagsinput-angular.js</code> and register the 'bootstrap-tagsinput' in your Angular JS application to use the bootstrap-tagsinput directive. </p> <div class="bs-example"> <bootstrap-tagsinput ng-model="cities" typeahead-source="queryCities" tagclass="getTagClass" itemvalue="value" itemtext="text"> </bootstrap-tagsinput> </div> <div class="accordion"> <div class="accordion-group"> <div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" href="#example_angular"> Show code </a> </div> <div id="example_angular" class="accordion-body collapse"> <div class="accordion-inner"> <pre><code data-language="html"><bootstrap-tagsinput ng-model="cities" typeahead-source="queryCities" tagclass="getTagClass" itemvalue="value" itemtext="text"> </bootstrap-tagsinput> <script> angular.module('AngularExample', ['bootstrap-tagsinput']) .controller('CityTagsInputController', function CityTagsInputController($scope) { // Init with some cities $scope.cities = [ { "value": 1 , "text": "Amsterdam" , "continent": "Europe" }, { "value": 4 , "text": "Washington" , "continent": "America" }, { "value": 7 , "text": "Sydney" , "continent": "Australia" }, { "value": 10, "text": "Beijing" , "continent": "Asia" }, { "value": 13, "text": "Cairo" , "continent": "Africa" } ]; $scope.queryCities = function(query) { return $http.get('cities.json'); }; $scope.getTagClass = function(city) { switch (city.continent) { case 'Europe' : return 'badge badge-info'; case 'America' : return 'label label-important'; case 'Australia': return 'badge badge-success'; case 'Africa' : return 'label label-inverse'; case 'Asia' : return 'badge badge-warning'; } }; } ); </script></code></pre> </div> </div> </div> </div> <table class="table table-bordered table-condensed"> <thead> <tr><th>statement</th><th>returns</th></tr> </thead> <tbody> <tr><td><code>$scope.cities</code></td><td><pre class="items"><code data-language="javascript"></code></pre>{{cities}}</td></tr> <tr><td><code>$("select").val()</code></td><td><pre class="val"><code data-language="javascript"></code></pre></td></tr> <tr><td><code>$("select").tagsinput('items')</code></td><td><pre class="items"><code data-language="javascript"></code></pre></td></tr> </tbody> </table> </div> </section --> <section id="options"> <div class="page-header"> <h2>Options</h2> </div> <table class="table table-bordered table-condensed"> <thead> <tr> <th colspan="2">option</th> <th>description</th> </tr> </thead> <tbody> <tr> <td colspan="2"><code>tagClass</code></td> <td> <p>Classname for the tags, or a function returning a classname</p> <pre><code data-language="javascript">$('input').tagsinput({ tagClass: 'big' });</code></pre> <pre><code data-language="javascript">$('input').tagsinput({ tagClass: function(item) { return (item.length > 10 ? 'big' : 'small'); } });</code></pre> </td> </tr> <tr> <td colspan="2"><code>itemValue</code></td> <td> <p>When adding objects as tags, itemValue <em>must</em> be set to the name of the property containing the item's value, or a function returning an item's value.</p> <pre><code data-language="javascript">$('input').tagsinput({ itemValue: 'id' });</code></pre> <pre><code data-language="javascript">$('input').tagsinput({ itemValue: function(item) { return item.id; } });</code></pre> </td> </tr> <tr> <td colspan="2"><code>itemText</code></td> <td> <p>When adding objects as tags, you can set itemText to the name of the property of item to use for a its tag's text. You may also provide a function which returns an item's value. When this options is not set, the value of <code>itemValue</code> will be used. <pre><code data-language="javascript">$('input').tagsinput({ itemText: 'label' });</code></pre> <pre><code data-language="javascript">$('input').tagsinput({ itemText: function(item) { return item.label; } });</code></pre> </td> </tr> <tr> <td colspan="2"><code>confirmKeys</code></td> <td> <p>Array of keycodes which will add a tag when typing in the input. (default: [13, 188], which are ENTER and comma)</p> <pre><code data-language="javascript">$('input').tagsinput({ confirmKeys: [13, 44] });</code></pre> </td> </tr> <tr> <td colspan="2"><code>maxTags</code></td> <td> <p>When set, no more than the given number of tags are allowed to add (default: undefined). When maxTags is reached, a class 'bootstrap-tagsinput-max' is placed on the tagsinput element.</p> <pre><code data-language="javascript">$('input').tagsinput({ maxTags: 3 });</code></pre> </td> </tr> <tr> <td colspan="2"><code>maxChars</code></td> <td> <p>Defines the maximum length of a single tag. (default: undefined)</p> <pre><code data-language="javascript">$('input').tagsinput({ maxChars: 8 });</code></pre> </td> </tr> <tr> <td colspan="2"><code>trimValue</code></td> <td> <p>When true, automatically removes all whitespace around tags. (default: false)</p> <pre><code data-language="javascript">$('input').tagsinput({ trimValue: true });</code></pre> </td> </tr> <tr> <td colspan="2"><code>allowDuplicates</code></td> <td> <p>When true, the same tag can be added multiple times. (default: false)</p> <pre><code data-language="javascript">$('input').tagsinput({ allowDuplicates: true });</code></pre> </td> </tr> <tr> <td colspan="2"><code>freeInput</code></td> <td> <p>Allow creating tags which are not returned by typeahead's source (default: true)</p> <div class="bs-callout bs-callout-warning"> This is only possible when using string as tags. When itemValue option is set, this option will be ignored. </div> <pre><code data-language="javascript">$('input').tagsinput({ typeahead: { source: ['Amsterdam', 'Washington', 'Sydney', 'Beijing', 'Cairo'] }, freeInput: true });</code></pre> </td> </tr> <tr> <td colspan="2"><code>typeahead</code></td> <td><p>Object containing typeahead specific options</td> </tr> </tr> <tr> <td></td> <td><code>source</code></td> <td> <p>An array (or function returning a promise or array), which will be used as source for a typeahead. <pre><code data-language="javascript">$('input').tagsinput({ typeahead: { source: ['Amsterdam', 'Washington', 'Sydney', 'Beijing', 'Cairo'] } });</code></pre> <pre><code data-language="javascript">$('input').tagsinput({ typeahead: { source: function(query) { return $.get('http://someservice.com'); } } });</code></pre> </td> </tr> <tr> <td colspan="2"><code>cancelConfirmKeysOnEmpty</code></td> <td><p>Boolean value controlling whether form submissions get processed when pressing enter in a field converted to a tagsinput (default: false). <pre><code data-language="javascript">$('input').tagsinput({ cancelConfirmKeysOnEmpty: true });</code></pre> </td> </tr> <tr> <td colspan="2"><code>onTagExists</code></td> <td><p>Function invoked when trying to add an item which allready exists. By default, the existing tag hides and fades in. <pre><code data-language="javascript">$('input').tagsinput({ onTagExists: function(item, $tag) { $tag.hide().fadeIn(); } });</code></pre> </td> </tr> </tbody> </table> </section> <section id="methods"> <div class="page-header"> <h2>Methods</h2> </div> <table class="table table-bordered table-condensed"> <thead> <tr> <th>method</th> <th>description</th> </tr> </thead> <tbody> <tr> <td><code>add</code></td> <td> <p>Adds a tag</p> <pre><code data-language="javascript">$('input').tagsinput('add', 'some tag');</code></pre> <pre><code data-language="javascript">$('input').tagsinput('add', { id: 1, text: 'some tag' });</code></pre> Optionally, you can pass a 3rd parameter (object or value) to the <code>add</code> method to gain more control over the process. The parameter is exposed in the <code>options</code> attribute of the event. <pre><code data-language="javascript">$('input').tagsinput('add', 'some tag', {preventPost: true});</code></pre> Usage: <pre> <code data-language="javascript"> $('#tags-input').on('beforeItemAdd', function(event) { var tag = event.item; // Do some processing here if (!event.options || !event.options.preventPost) { $.ajax('/ajax-url', ajaxData, function(response) { if (response.failure) { // Remove the tag since there was a failure // "preventPost" here will stop this ajax call from running when the tag is removed $('#tags-input').tagsinput('remove', tag, {preventPost: true}); } }); } }); </code> </pre> </td> </tr> <tr> <td><code>remove</code></td> <td> <p>Removes a tag</p> <pre><code data-language="javascript">$('input').tagsinput('remove', 'some tag');</code></pre> <pre><code data-language="javascript">$('input').tagsinput('remove', { id: 1, text: 'some tag' });</code></pre> Optionally, you can pass a 3rd parameter (object or value) to the <code>remove</code> method to gain more control over the process. The parameter is exposed in the <code>options</code> attribute of the event. <pre><code data-language="javascript">$('input').tagsinput('remove', 'some tag', {preventPost: true});</code></pre> Usage: <pre> <code data-language="javascript"> $('#tags-input').on('beforeItemRemove', function(event) { var tag = event.item; // Do some processing here if (!event.options || !event.options.preventPost) { $.ajax('/ajax-url', ajaxData, function(response) { if (response.failure) { // Re-add the tag since there was a failure // "preventPost" here will stop this ajax call from running when the tag is added $('#tags-input').tagsinput('add', tag, {preventPost: true}); } }); } }); </code> </pre> </td> </tr> <tr> <td><code>removeAll</code></td> <td> <p>Removes all tags</p> <pre><code data-language="javascript">$('input').tagsinput('removeAll');</code></pre> </td> </tr> <tr> <td><code>focus</code></td> <td> <p>Sets focus in the tagsinput</p> <pre><code data-language="javascript">$('input').tagsinput('focus');</code></pre> </td> </tr> <tr> <td><code>input</code></td> <td> <p>Returns the tagsinput's internal <input />, which is used for adding tags. You could use this to add your own typeahead behaviour for example.</p> <pre><code data-language="html">var $elt = $('input').tagsinput('input');</code></pre> </td> </tr> <tr> <td><code>refresh</code></td> <td> <p>Refreshes the tags input UI. This might be usefull when you're adding objects as tags. When an object's text changes, you'll have to refresh to update the matching tag's text.</p> <pre><code data-language="javascript">$('input').tagsinput('refresh');</code></pre> </td> </tr> <tr> <td><code>destroy</code></td> <td> <p>Removes tagsinput behaviour</p> <pre><code data-language="javascript">$('input').tagsinput('destroy');</code></pre> </td> </tr> </tbody> </table> </section> <section id="methods"> <div class="page-header"> <h2>Events</h2> </div> <table class="table table-bordered table-condensed"> <thead> <tr> <th>event</th> <th>description</th> </tr> </thead> <tbody> <tr> <td><code>itemAddedOnInit</code></td> <td> During initialization, pre-defined tags being added will cause this event to be triggered. Example: <pre><code data-language="javascript">$('input').on('itemAddedOnInit', function(event) { // event.item: contains the item });</code></pre> </td> </tr> <tr> <td><code>beforeItemAdd</code></td> <td> Triggered just before an item gets added. Example: <pre><code data-language="javascript">$('input').on('beforeItemAdd', function(event) { // event.item: contains the item // event.cancel: set to true to prevent the item getting added });</code></pre> </td> </tr> <tr> <td><code>itemAdded</code></td> <td> Triggered just after an item got added. Example: <pre><code data-language="javascript">$('input').on('itemAdded', function(event) { // event.item: contains the item });</code></pre> </td> </tr> <tr> <td><code>beforeItemRemove</code></td> <td> Triggered just before an item gets removed. Example: <pre><code data-language="javascript">$('input').on('beforeItemRemove', function(event) { // event.item: contains the item // event.cancel: set to true to prevent the item getting removed });</code></pre> </td> </tr> <tr> <td><code>itemRemoved</code></td> <td> Triggered just after an item got removed. Example: <pre><code data-language="javascript">$('input').on('itemRemoved', function(event) { // event.item: contains the item });</code></pre> </td> </tr> </tbody> </table> </section> </div> <footer class="footer"> <div class="container"> <p>Code licensed under <a href="https://raw.github.com/TimSchlechter/bootstrap-tagsinput/master/LICENSE" target="_blank">MIT License</a></p> </div> </footer> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script> <script src="../dist/bootstrap-tagsinput.min.js"></script> <script src="../dist/bootstrap-tagsinput/bootstrap-tagsinput-angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/js/rainbow.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/js/language/generic.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/js/language/html.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/rainbow/1.2.0/js/language/javascript.js"></script> <script src="assets/app.js"></script> <script src="assets/app_bs3.js"></script> </body> </html> README.md000064400000011762151676724710006052 0ustar00# Bootstrap Tags Input [](https://travis-ci.org/bootstrap-tagsinput/bootstrap-tagsinput) Bootstrap Tags Input is a jQuery plugin providing a Twitter Bootstrap user interface for managing tags. Current stable version: **v0.7.1** ## Usage Examples can be found [here](http://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/). ## Features * Objects as tags * True multi value * Typeahead * Designed for Bootstrap 2.3.2 and 3 ### Objects as tags Not just support for using strings! This means you can use different values for a tag's label and value. Each tag also holds a reference to the object by which it was created, so by calling <code>tagsinput('items')</code> an array of the original items is returned. ### True multi value support Other implementations just concatenate the values to a comma separated string. This results in <code>val()</code> returning just this string, and when submitting the form, only one big, concatenated value is sent in the request. Bootstrap Tags Input provides true multivalue support. Just use a <code><select multiple /></code> as your input element, and <code>val()</code> will return an array of the tag values. When submitting the form, an array of values will be sent with the request. ### Typeahead support Integrates with Twitter Bootstraps' 2.3.2 typeahead, or use custom typeahead when using Bootstrap 3. ## Development Install dependencies: <pre> npm install grunt install </pre> Test: <pre> grunt test </pre> Build: <pre> grunt build </pre> Current Library Versions: - Bootstrap: 3.3.5 - jQuery: 2.1.4 - Typeahead: 0.11.1 Libraries for testing go in the **/lib** directory. ## History - 0.7.1 - [allowDuplicates not working](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/419) - [tag text appears when typeahead input looses focus](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/386) - [Remove duplicate method `removeAll` in manual](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/pull/427) - 0.7.0 - [.tt-menu etc. styles should be included in bootstrap-tagsinput.css by default](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/426) - [Comma character carried over to new tag input when used as separator](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/422) - [Emails in multi select are being duplicated](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/399) - [The 'itemAdded' Event run on Load the Page!](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/369) - 0.6.1 - [Source maps fix](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/371) - 0.6.0 - [Allow form submissions when pressing enter if field is empty. Controlled by option](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/368) - [Ability to set different or multiple delimiters](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/397) - [No longer triggering itemRemoved when the field is already empty](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/405) - 0.5 - [Added an optional 3rd parameter to the "add" and "remove" methods](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/pull/298) - 0.4 - [Fix typeahead when using Bootstrap 3](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/pull/73) - 0.3.13 - [#5: Trigger events on original input/select](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/5) - Loads of fixes merged with help of @janvt, @rlidwka and @kuraga: thanks for helping me out! - 0.3.9 - [#48: Type ahead stops when entering second character](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/48) - 0.3.8 - [#43: Add support for placeholder](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/pull/43) - [#46: ie 8 compatibility, replace indexOf method](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/pull/46) - 0.3.7 - [#39: flash when duplicate is entered](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/39) - 0.3.6 - [#34: Error in ReloadPage](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/34) - 0.3.5 - [#10: confirmKeys option](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/issues/10) - 0.3.4 - [#24: Add bsTagsInput angular directive & example for bootstrap3 with typeahea...](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/pull/24) - [#28: Limit number of tags, enable/disable input](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/pull/28) - [#33: Avoid conflict with other selects when checking for value presence](https://github.com/bootstrap-tagsinput/bootstrap-tagsinput/pull/33) ## License This project is licensed under [MIT](https://raw.github.com/bootstrap-tagsinput/bootstrap-tagsinput/master/LICENSE "Read more about the MIT license"). bower.json000064400000001632151676724720006600 0ustar00{ "name": "bootstrap-tagsinput", "version": "0.5.0", "homepage": "https://github.com/TimSchlechter/bootstrap-tagsinput", "authors": [ "Tim Schlechter", "Luckner Jr Jean-Baptiste" ], "description": "jQuery plugin providing a Twitter Bootstrap user interface for managing tags.", "main": [ "dist/bootstrap-tagsinput.js", "dist/bootstrap-tagsinput.css" ], "keywords": [ "tags", "bootstrap", "input", "select", "form" ], "license": "MIT", "ignore": [ "**/.*", "node_modules", "bower_components", "lib", "test" ], "dependencies": { "jquery": "~2.1.1" }, "devDependencies": { "bootstrap-3": "bootstrap#~3.2.0", "bootstrap-2.3.2": "bootstrap#~2.3.2", "angular": "~1.2.21", "typeahead.js": "~0.10.4", "jasmine": "~2.0.1" }, "resolutions": { "jquery": ">= 1.9.0" } } input_with_object_items.tests.js000064400000010560151701440430013165 0ustar00describe("bootstrap-tagsinput", function() { describe("with objects as items", function() { testTagsInput('<input type="text" />', function() { it("adding a item should throw an exception", function() { var element = this.$element; expect(function() { element.tagsinput('add', {}); }).toThrow("Can't add objects when itemValue option is not set"); }); }); testTagsInput('<input type="text" />', { itemValue: function(item) { return item.value; } }, function() { describe("adding an item", function() { var item; beforeEach(function() { item = { value: 1 }; this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("val() should return the item's value", function() { expect(this.$element.val()).toBe("1"); }); it("tag's text should be the item's value", function() { expect($('.tag', this.$sandbox).text()).toBe("1"); }); }); }); testTagsInput('<input type="text" />', { itemValue: 'value' }, function() { describe("adding an item", function() { var item; beforeEach(function() { item = { value: 1 }; this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("'items' should returns exactly 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); it("val() should return the item's value", function() { expect(this.$element.val()).toBe("1"); }); it("tag's text should be the item's value", function() { expect($('.tag', this.$sandbox).text()).toBe("1"); }); }); }); testTagsInput('<input type="text" />', { itemValue: function(item) { return item.value; }, itemText: function(item) { return item.text; } }, function() { describe("adding an item", function() { var item = { value: 1, text: 'some' }; beforeEach(function() { this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("val() should return the item's value", function() { expect(this.$element.val()).toBe("1"); }); it("tag's text should be the item's text", function() { expect($('.tag', this.$sandbox).text()).toBe("some"); }); describe("change item and invoke 'refesh'", function() { beforeEach(function() { item.text = 'changed'; this.$element.tagsinput('refresh'); }); it("should update tags's text", function() { expect($('.tag', this.$sandbox).text()).toBe('changed'); }); it("tag should still have remove button", function() { expect($('[data-role=remove]', this.$sandbox)[0]).not.toBeUndefined(); }); }); }); }); testTagsInput('<input type="text" />', { itemValue: function(item) { return item.value; }, itemText: function(item) { return item.text; }, itemTitle: function(item) { return item.title; } }, function() { describe("adding an item with a title", function() { var item; beforeEach(function() { item = { value: 1, text: 'one', title: 'number one' }; this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("'items' should returns exactly 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); it("val() should return the item's value", function() { expect(this.$element.val()).toBe("1"); }); it("tag's text should be the item's value", function() { expect($('.tag', this.$sandbox).text()).toBe("one"); }); it("tag's title should be the item's title", function() { expect($('.tag', this.$sandbox).attr('title')).toBe("number one"); }); }); }); }); });reproduced_bugs.tests.js000064400000014511151701440430011420 0ustar00describe("bootstrap-tagsinput", function() { describe("Reproduced bugs", function() { describe("#1: Demo error", function() { testTagsInput('<input type="text" value="some_tag" />', function() { it("clicking remove button should remove item", function() { $('[data-role=remove]', this.$sandbox).trigger('click'); expect(this.$element.tagsinput('items').length).toBe(0); }); it("clicking remove button should remove tag element", function() { $('[data-role=remove]', this.$sandbox).trigger('click'); expect($('.tag', this.$sandbox).length).toBe(0); }); }); }); describe("#11: Cannot remove an item by programming", function() { testTagsInput('<input type="text" />', { itemValue: function(item) { return item.value; } }, function() { describe("add two different objects with same value", function() { var item1 = { value: 1 }, item2 = { value: 1 }; beforeEach(function() { this.$element.tagsinput('add', item1); this.$element.tagsinput('add', item2); }); it("'items' should return the first added item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item1); }); it("'items' should return exactly 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); it("should have exactly 1 tag", function() { expect($('.tag', this.$sandbox).length).toBe(1); }); }); describe("remove item", function() { beforeEach(function() { this.$element.tagsinput('add', { value: 1 }); }); it("by value, should remove then item", function() { this.$element.tagsinput('remove', 1); expect(this.$element.tagsinput('items').length).toBe(0); }); it("by value, should remove then tag", function() { this.$element.tagsinput('remove', 1); expect($('.tag', this.$sandbox).length).toBe(0); }); it("by different instance, should remove then tag", function() { this.$element.tagsinput('remove', { value: 1 }); expect($('.tag', this.$sandbox).length).toBe(0); }); it("should remove items when none of the items have a matching value", function() { this.$element.tagsinput('add', { value: 1 }); this.$element.tagsinput('remove', 2); expect(this.$element.tagsinput('items').length).toBe(1); }); }); }); testTagsInput('<select />', { itemValue: function(item) { return item.value; } }, function() { describe("add two objects", function() { var item1 = { value: 1 }, item2 = { value: 2 }; beforeEach(function() { this.$element.tagsinput('add', item1); this.$element.tagsinput('add', item2); }); it("'items' should return the last added item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item2); }); it("'items' should return exactly 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); it("should have exactly 1 tag", function() { expect($('.tag', this.$sandbox).length).toBe(1); }); it("val() should return first item's value", function() { expect(this.$element.val()).toBe("2"); }); }); }); }); describe("#34: Error in ReloadPage", function() { describe("init tagsinput with objects as items, but with value set on element", function() { testTagsInput('<input type="text" value="1" />', { itemValue: function(item) { return item.value; } }, function() { it("should have no tags", function() { expect(this.$element.tagsinput('items').length).toBe(0); }); }); testTagsInput('<select><option value="1" /></select>', { itemValue: function(item) { return item.value; } }, function() { it("should have no tags", function() { expect(this.$element.tagsinput('items').length).toBe(0); }); }); }); }); describe("#90: Error in reinitialization (arg1 and arg2 are undefined)", function() { describe("init tagsinput twice", function() { testTagsInput('<input type="text" value="1" />', { itemValue: function(item) { return item.value; } }, function() { it("should not fail if an element is reinitialized", function () { this.$element.tagsinput(); }); it("should return the original instance if already initialized", function () { return this.$element.tagsinput() === this; }); }); }); }); describe("#142: Initialization of Null Values for Multi Select field", function() { testTagsInput('<select multiple data-role="tagsinput"></select>', function() { it("Initializing an empty select shouldn't throw an error.", function() { $("select[multiple][data-role=tagsinput]").tagsinput(); }); }); }); describe("#128: Custom classes for tags don't work if entered as strings", function() { testTagsInput('<input type="text" value="1" />', { tagClass: 'big' }, function() { it("should have a tag with class 'big' when using tagClass option as string", function() { expect($(".big", this.$tagsinput).length).toBe(1); }); }); testTagsInput('<input type="text" value="1" />', { tagClass: function() { return 'big'; } }, function() { it("should have a tag with class 'big' when using tagClass option as function", function() { expect($(".big", this.$tagsinput).length).toBe(1); }); }); }); describe("#107: Fixed bug when removing items", function() { testTagsInput('<input type="text" value="yes,no" />', function() { it("should not remove items when remove a non-existing item", function() { this.$element.tagsinput('remove', 'maybe'); expect(this.$element.tagsinput('items').length).toBe(2); }); }); }); }); });input_with_string_items.tests.js000064400000017114151701440430013227 0ustar00describe("bootstrap-tagsinput", function() { describe("with strings as items", function() { testTagsInput('<input type="text" />', { trimValue: true }, function(){ it("trim item values", function() { this.$element.tagsinput('add', ' some_tag '); this.$element.tagsinput('add', 'some_tag '); expect(this.$element.val()).toBe('some_tag'); }); }); testTagsInput('<input type="text" />', function() { it("should hide input", function() { expect(this.$element.css('display')).toBe('none'); }); it("should add tag on when pressing ENTER", function() { this.$tagsinput_input.val('some_tag'); this.$tagsinput_input.trigger($.Event('keypress', { which: 13 })); expect(this.$element.tagsinput('items').length).toBe(1); }); it("should add tag on when pressing COMMA ,", function() { this.$tagsinput_input.val('some_tag'); this.$tagsinput_input.trigger($.Event('keypress', { which: 44 })); expect(this.$element.tagsinput('items').length).toBe(1); }); describe("should not add tag", function() { it("when adding same item twice", function() { this.$element.tagsinput('add', 'some_tag'); this.$element.tagsinput('add', 'some_tag'); expect(this.$element.val()).toBe('some_tag'); }); it("when adding empty string", function() { this.$element.tagsinput('add', ''); expect(this.$element.tagsinput('items').length).toBe(0); }); it("when adding whitespace string", function() { this.$element.tagsinput('add', ' '); expect(this.$element.tagsinput('items').length).toBe(0); }); it("when adding undefined", function() { this.$element.tagsinput('add', undefined); expect(this.$element.tagsinput('items').length).toBe(0); }); it("when adding null", function() { this.$element.tagsinput('add', null); expect(this.$element.tagsinput('items').length).toBe(0); }); }); describe("should add tag", function() { it("when adding boolean false", function() { this.$element.tagsinput('add', false); expect(this.$element.tagsinput('items').length).toBe(1); }); it("when adding boolean true", function() { this.$element.tagsinput('add', false); expect(this.$element.tagsinput('items').length).toBe(1); }); }); describe("invoke 'add' with a string", function() { beforeEach(function() { this.$element.tagsinput('add', 'some_tag'); }); it("val() should return 'some_tag'", function() { expect(this.$element.val()).toBe('some_tag'); }); it("'items' should return 1 item", function() { expect(this.$element.tagsinput('items').length).toBe(1); }); describe("invoking 'remove'", function() { beforeEach(function() { this.$element.tagsinput('remove', 'some_tag'); }); it("val() should should return null", function() { expect(this.$element.val()).toBe(''); }); }); }); describe("invoke 'add' with a string containing a comma", function() { beforeEach(function() { this.$element.tagsinput('add', 'before,after'); }); it("val() should return 'before,after'", function() { expect(this.$element.val()).toBe('before,after'); }); it("'items' should return 2 items", function() { expect(this.$element.tagsinput('items').length).toBe(2); }); }); it("'focus' should place focus in input", function() { this.$element.tagsinput('focus'); expect(hasFocus(this.$tagsinput_input)).toBe(true); }); }); testTagsInput('<input type="text" value="some,tags" />', function() { it('should have 2 tags', function() { expect(this.$element.tagsinput('items').length).toBe(2); }); describe("invoke 'removeAll'", function() { beforeEach(function() { this.$element.tagsinput('removeAll'); }); it("should remove both tags", function() { expect(this.$element.tagsinput('items').length).toBe(0); }); it("val() should return ''", function() { expect(this.$element.val()).toBe(''); }); }); describe("BACKSPACE", function() { beforeEach(function() { this.$element.tagsinput('focus'); }); it('after last tag, should remove the last tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 8 })); expect(this.$element.tagsinput('items')[0]).toBe('some'); }); it('after last tag, should remove the last tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 8 })); expect(this.$element.tagsinput('items').length).toBe(1); }); it('after first tag, should remove the first tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 37 })); this.$tagsinput_input.trigger($.Event('keydown', { which: 8 })); expect(this.$element.tagsinput('items')[0]).toBe('tags'); }); }); describe("DELETE", function() { beforeEach(function() { this.$element.tagsinput('focus'); // move cursor before last tag this.$tagsinput_input.trigger($.Event('keydown', { which: 37 })); }); it('before last tag, should remove the last tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 46 })); expect(this.$element.tagsinput('items')[0]).toBe('some'); }); it('before last tag, should remove the last tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 46 })); expect(this.$element.tagsinput('items').length).toBe(1); }); it('before first tag, should remove the first tag', function() { this.$tagsinput_input.trigger($.Event('keydown', { which: 37 })); this.$tagsinput_input.trigger($.Event('keydown', { which: 46 })); expect(this.$element.tagsinput('items')[0]).toBe('tags'); }); }); }); testTagsInput('<input type="text" value="some,tag"/>', { maxTags: 2 }, function() { it("should have class 'bootstrap-tagsinput-max'", function() { expect(this.$tagsinput.hasClass('bootstrap-tagsinput-max')).toBe(true); }); describe("adding another tag", function() { it("should not add the tag", function() { this.$element.tagsinput('add', 'another'); expect(this.$element.tagsinput('items').length).toBe(2); }); }); describe("removing a tags", function() { it("should not have class 'bootstrap-tagsinput-max'", function() { this.$element.tagsinput('remove', 'some'); expect(this.$tagsinput.hasClass('bootstrap-tagsinput-max')).toBe(false); }); }) }); testTagsInput('<input type="text" />', { confirmKeys: [9] }, function() { it("should add tag on when pressing TAB", function() { this.$tagsinput_input.val('some_tag'); this.$tagsinput_input.trigger($.Event('keypress', { which: 9 })); expect(this.$element.tagsinput('items').length).toBe(1); }); }); }); }); select_with_string_items.tests.js000064400000002747151701440430013355 0ustar00describe("bootstrap-tagsinput", function() { describe("with strings as items", function() { testTagsInput("<select multiple />", function() { describe("when added 1 item", function() { beforeEach(function() { this.$element.tagsinput('add', 'some_tag'); }); it("val() should return array containing 1 item", function() { expect(this.$element.val()[0]).toBe('some_tag'); }); describe("invoking 'remove'", function() { beforeEach(function() { this.$element.tagsinput('remove', 'some_tag'); }); it("val() should should return null", function() { expect(this.$element.val()).toBeNull(); }); it("there should be no <option /> elements", function() { expect($("option", this.$sandbox).length).toBe(0); }); }); }); describe("when added item containing a comma", function() { beforeEach(function() { this.$element.tagsinput('add', 'before,after'); }); it("val() should return array containing 1 item", function() { expect(this.$element.val()[0]).toBe('before,after'); }); }); }); testTagsInput('<select multiple><option value="some">some</option></select>', function() { it('should have one tag', function() { expect(this.$element.tagsinput('items')[0]).toBe('some'); }); }); }); });select_with_object_items.tests.js000064400000002655151701440430013313 0ustar00describe("bootstrap-tagsinput", function() { describe("with objects as items", function() { testTagsInput('<select multiple />', { itemValue: function(item) { return item.value; }, itemText: function(item) { return item.text; } }, function() { describe("adding an item", function() { var item; beforeEach(function() { item = { value: 1, text: 'some' }; this.$element.tagsinput('add', item); }); it("'items' should return the item", function() { expect(this.$element.tagsinput('items')[0]).toBe(item); }); it("val() should return the item's value", function() { expect(this.$element.val()[0]).toBe("1"); }); it("tag's text should be the item's text", function() { expect($('.tag', this.$sandbox).text()).toBe("some"); }); describe("change item's value and text and invoke 'refesh'", function() { beforeEach(function() { item.value = 2; item.text = 'changed'; this.$element.tagsinput('refresh'); }); it("should update tags's text", function() { expect($('.tag', this.$sandbox).text()).toBe('changed'); }); it("val() should return item's new value", function() { expect(this.$element.val()[0]).toBe("2"); }); }); }); }); }); });events.tests.js000064400000001447151701440430007554 0ustar00describe("bootstrap-tagsinput", function() { describe("events", function() { testTagsInput('<input type="text" />', function() { it("beforeItemAdd canceled", function() { this.$element.on('beforeItemAdd', function(event) { event.cancel = true; }); this.$element.tagsinput('add', 'some'); expect(this.$element.tagsinput('items').length).toBe(0); }); }); testTagsInput('<input type="text" value="1" />', function() { it("beforeItemRemove canceled", function() { this.$element.on('beforeItemRemove', function(event) { event.cancel = true; }); this.$element.tagsinput('remove', '1'); expect(this.$element.tagsinput('items').length).toBe(1); }); }); }); });
/home/emeraadmin/.razor/./../www/node_modules/parse-filepath/../../4d695/bootstrap-tagsinput.tar