diff --git a/build/ng-tags-input.css b/build/ng-tags-input.css index 26ade869..6e3003b1 100644 --- a/build/ng-tags-input.css +++ b/build/ng-tags-input.css @@ -24,6 +24,7 @@ overflow-x: hidden; word-wrap: break-word; font-size: 14px; + cursor: text; } .ngTagsInput .tags.focused { @@ -33,14 +34,14 @@ box-shadow: 0px 0px 3px 1px rgba(5,139,242,0.6); } -.ngTagsInput .tags ul { +.ngTagsInput .tags .tag-list { margin: 0px; padding: 0px; overflow: visible; list-style-type: none; } -.ngTagsInput .tags li { +.ngTagsInput .tags .tag-item { margin: 2px; padding-left: 4px; display: inline-block; @@ -56,10 +57,9 @@ background: -o-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* Opera 11.10+ */ background: -ms-linear-gradient(top, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* IE10+ */ background: linear-gradient(to bottom, rgba(240,249,255,1) 0%,rgba(203,235,255,1) 47%,rgba(161,219,255,1) 100%); /* W3C */ - } -.ngTagsInput .tags li.selected { +.ngTagsInput .tags .tag-item.selected { background: rgb(254,187,187); /* Old browsers */ background: -moz-linear-gradient(top, rgba(254,187,187,1) 0%, rgba(254,144,144,1) 45%, rgba(255,92,92,1) 100%); /* FF3.6+ */ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(254,187,187,1)), color-stop(45%,rgba(254,144,144,1)), color-stop(100%,rgba(255,92,92,1))); /* Chrome,Safari4+ */ @@ -69,11 +69,11 @@ background: linear-gradient(to bottom, rgba(254,187,187,1) 0%,rgba(254,144,144,1) 45%,rgba(255,92,92,1) 100%); /* W3C */ } -.ngTagsInput .tags span { +.ngTagsInput .tags .tag-item span { font: 13px "Helvetica Neue", Helvetica, Arial, sans-serif; } -.ngTagsInput .tags button { +.ngTagsInput .tags .tag-item button { margin: 0px; border: none; background: none; @@ -83,11 +83,11 @@ vertical-align: middle; } -.ngTagsInput .tags button:active { +.ngTagsInput .tags .tag-item button:active { color: #ff0000; } -.ngTagsInput .tags input { +.ngTagsInput .tags .tag-input { border: 0px; outline: none; margin: 2px; @@ -113,13 +113,13 @@ z-index: 999; } -.ngTagsInput .autocomplete ul { +.ngTagsInput .autocomplete .suggestion-list { margin: 0; padding: 0; list-style-type: none; } -.ngTagsInput .autocomplete li { +.ngTagsInput .autocomplete .suggestion-item { padding: 3px 16px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; @@ -131,12 +131,12 @@ text-overflow: ellipsis; } -.ngTagsInput .autocomplete li.selected { +.ngTagsInput .autocomplete .suggestion-item.selected { color: #fff; background-color: #0097cf } -.ngTagsInput .autocomplete li em { +.ngTagsInput .autocomplete .suggestion-item em { font-weight: bold; font-style: normal; } \ No newline at end of file diff --git a/build/ng-tags-input.js b/build/ng-tags-input.js index 87315250..935b9a4d 100644 --- a/build/ng-tags-input.js +++ b/build/ng-tags-input.js @@ -40,7 +40,7 @@ var tagsInput = angular.module('ngTagsInput', []); * @param {expression} onTagAdded Expression to evaluate upon adding a new tag. The new tag is available as $tag. * @param {expression} onTagRemoved Expression to evaluate upon removing an existing tag. The removed tag is available as $tag. */ -tagsInput.directive('tagsInput', ["$timeout","$document","tagsInputConfig", function($timeout, $document, tagsInputConfig) { +tagsInput.directive('tagsInput', ["$timeout","$document","tiConfiguration", function($timeout, $document, tiConfiguration) { function SimplePubSub() { var events = {}; @@ -73,7 +73,7 @@ tagsInput.directive('tagsInput', ["$timeout","$document","tagsInputConfig", func var events = new SimplePubSub(), shouldRemoveLastTag; - tagsInputConfig.load($scope, $attrs, { + tiConfiguration.load($scope, $attrs, { customClass: { type: String, defaultValue: '' }, placeholder: { type: String, defaultValue: 'Add a tag' }, tabindex: { type: Number }, @@ -265,7 +265,7 @@ tagsInput.directive('tagsInput', ["$timeout","$document","tagsInputConfig", func * suggestions list. * @param {number=} [maxResultsToShow=10] Maximum number of results to be displayed at a time. */ -tagsInput.directive('autoComplete', ["$document","$timeout","$sce","tagsInputConfig", function($document, $timeout, $sce, tagsInputConfig) { +tagsInput.directive('autoComplete', ["$document","$timeout","$sce","tiConfiguration", function($document, $timeout, $sce, tiConfiguration) { function SuggestionList(loadFn, options) { var self = {}, debouncedLoadId, getDifference, lastPromise; @@ -364,7 +364,7 @@ tagsInput.directive('autoComplete', ["$document","$timeout","$sce","tagsInputCon var hotkeys = [KEYS.enter, KEYS.tab, KEYS.escape, KEYS.up, KEYS.down], suggestionList, tagsInput, markdown; - tagsInputConfig.load(scope, attrs, { + tiConfiguration.load(scope, attrs, { debounceDelay: { type: Number, defaultValue: 100 }, minLength: { type: Number, defaultValue: 3 }, highlightMatchedText: { type: Boolean, defaultValue: true }, @@ -475,12 +475,12 @@ tagsInput.directive('autoComplete', ["$document","$timeout","$sce","tagsInputCon /** * @ngdoc directive - * @name tagsInput.directive:transcludeAppend + * @name tagsInput.directive:tiTranscludeAppend * * @description - * Re-creates the old behavior of ng-transclude. + * Re-creates the old behavior of ng-transclude. Used internally by tagsInput directive. */ -tagsInput.directive('transcludeAppend', function() { +tagsInput.directive('tiTranscludeAppend', function() { return function(scope, element, attrs, ctrl, transcludeFn) { transcludeFn(function(clone) { element.append(clone); @@ -488,14 +488,59 @@ tagsInput.directive('transcludeAppend', function() { }; }); +/** + * @ngDoc directive + * @name tagsInput.directive:tiAutosize + * + * @description + * Automatically sets the input's width so its content is always visible. Used internally by tagsInput directive. + */ +tagsInput.directive('tiAutosize', function() { + return { + restrict: 'A', + require: 'ngModel', + link: function(scope, element, attrs, ctrl) { + var span, resize; + + span = angular.element(''); + span.css('display', 'none') + .css('visibility', 'hidden') + .css('width', 'auto'); + + element.parent().append(span); + + resize = function(value) { + var originalValue = value; + + if (angular.isString(value) && value.length === 0) { + value = element.attr('placeholder') || ''; + } + span.text(value); + span.css('display', ''); + try { + element.css('width', span.prop('offsetWidth') + 'px'); + } + finally { + span.css('display', 'none'); + } + + return originalValue; + }; + + ctrl.$parsers.unshift(resize); + ctrl.$formatters.unshift(resize); + } + }; +}); + /** * @ngdoc service - * @name tagsInput.service:tagsInputConfig + * @name tagsInput.service:tiConfiguration * * @description - * Loads and initializes options from HTML attributes. Used internally for tagsInput and autoComplete directives. + * Loads and initializes options from HTML attributes. Used internally by tagsInput and autoComplete directives. */ -tagsInput.service('tagsInputConfig', ["$interpolate", function($interpolate) { +tagsInput.service('tiConfiguration', ["$interpolate", function($interpolate) { this.load = function(scope, attrs, options) { var converters = {}; converters[String] = function(value) { return value; }; @@ -517,11 +562,11 @@ tagsInput.service('tagsInputConfig', ["$interpolate", function($interpolate) { tagsInput.run(["$templateCache", function($templateCache) { $templateCache.put('ngTagsInput/tags-input.html', - "
" + "
" ); $templateCache.put('ngTagsInput/auto-complete.html', - "
" + "
" ); }]); diff --git a/build/ng-tags-input.min.zip b/build/ng-tags-input.min.zip index 58f25de6..c3889ede 100644 Binary files a/build/ng-tags-input.min.zip and b/build/ng-tags-input.min.zip differ diff --git a/build/ng-tags-input.zip b/build/ng-tags-input.zip index ae372f27..eb61484a 100644 Binary files a/build/ng-tags-input.zip and b/build/ng-tags-input.zip differ diff --git a/src/auto-complete.js b/src/auto-complete.js index d7dd25d0..57896622 100644 --- a/src/auto-complete.js +++ b/src/auto-complete.js @@ -18,7 +18,7 @@ * suggestions list. * @param {number=} [maxResultsToShow=10] Maximum number of results to be displayed at a time. */ -tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInputConfig) { +tagsInput.directive('autoComplete', function($document, $timeout, $sce, tiConfiguration) { function SuggestionList(loadFn, options) { var self = {}, debouncedLoadId, getDifference, lastPromise; @@ -117,7 +117,7 @@ tagsInput.directive('autoComplete', function($document, $timeout, $sce, tagsInpu var hotkeys = [KEYS.enter, KEYS.tab, KEYS.escape, KEYS.up, KEYS.down], suggestionList, tagsInput, markdown; - tagsInputConfig.load(scope, attrs, { + tiConfiguration.load(scope, attrs, { debounceDelay: { type: Number, defaultValue: 100 }, minLength: { type: Number, defaultValue: 3 }, highlightMatchedText: { type: Boolean, defaultValue: true }, diff --git a/src/configuration.js b/src/configuration.js index 438ab7f4..187c6c60 100644 --- a/src/configuration.js +++ b/src/configuration.js @@ -2,12 +2,12 @@ /** * @ngdoc service - * @name tagsInput.service:tagsInputConfig + * @name tagsInput.service:tiConfiguration * * @description - * Loads and initializes options from HTML attributes. Used internally for tagsInput and autoComplete directives. + * Loads and initializes options from HTML attributes. Used internally by tagsInput and autoComplete directives. */ -tagsInput.service('tagsInputConfig', function($interpolate) { +tagsInput.service('tiConfiguration', function($interpolate) { this.load = function(scope, attrs, options) { var converters = {}; converters[String] = function(value) { return value; }; diff --git a/src/tags-input.js b/src/tags-input.js index a0bc904e..265f8481 100644 --- a/src/tags-input.js +++ b/src/tags-input.js @@ -28,7 +28,7 @@ var tagsInput = angular.module('ngTagsInput', []); * @param {expression} onTagAdded Expression to evaluate upon adding a new tag. The new tag is available as $tag. * @param {expression} onTagRemoved Expression to evaluate upon removing an existing tag. The removed tag is available as $tag. */ -tagsInput.directive('tagsInput', function($timeout, $document, tagsInputConfig) { +tagsInput.directive('tagsInput', function($timeout, $document, tiConfiguration) { function SimplePubSub() { var events = {}; @@ -61,7 +61,7 @@ tagsInput.directive('tagsInput', function($timeout, $document, tagsInputConfig) var events = new SimplePubSub(), shouldRemoveLastTag; - tagsInputConfig.load($scope, $attrs, { + tiConfiguration.load($scope, $attrs, { customClass: { type: String, defaultValue: '' }, placeholder: { type: String, defaultValue: 'Add a tag' }, tabindex: { type: Number }, diff --git a/src/transclude-append.js b/src/transclude-append.js index dccb00a0..54a523d9 100644 --- a/src/transclude-append.js +++ b/src/transclude-append.js @@ -2,12 +2,12 @@ /** * @ngdoc directive - * @name tagsInput.directive:transcludeAppend + * @name tagsInput.directive:tiTranscludeAppend * * @description - * Re-creates the old behavior of ng-transclude. + * Re-creates the old behavior of ng-transclude. Used internally by tagsInput directive. */ -tagsInput.directive('transcludeAppend', function() { +tagsInput.directive('tiTranscludeAppend', function() { return function(scope, element, attrs, ctrl, transcludeFn) { transcludeFn(function(clone) { element.append(clone); diff --git a/templates/tags-input.html b/templates/tags-input.html index 6b2472b2..7e5ebac5 100644 --- a/templates/tags-input.html +++ b/templates/tags-input.html @@ -1,4 +1,4 @@ -
+
  • diff --git a/test/transclude-append.spec.js b/test/transclude-append.spec.js index efba3853..2b84d36f 100644 --- a/test/transclude-append.spec.js +++ b/test/transclude-append.spec.js @@ -34,7 +34,7 @@ describe('transclude-append-directive', function () { it('appends the transcluded content to the end of an empty target element', function() { // Arrange - createDirective('
    '); + createDirective('
    '); // Act compile('

    transcluded content

    '); @@ -45,7 +45,7 @@ describe('transclude-append-directive', function () { it('appends the transcluded content to the end of a non-empty target element', function() { // Arrange - createDirective('

    existing content

    '); + createDirective('

    existing content

    '); // Act compile('

    transcluded content

    ');