From 8abdf79bcd6871cd7c7064838020ea2b6c7b2fa2 Mon Sep 17 00:00:00 2001 From: Michael Benford Date: Tue, 24 Dec 2013 01:00:57 -0200 Subject: [PATCH] fix(tagsInput): Change input width accordingly to its content Create a new directive to dynamically change the input width so its content is always visible. For that directive to work, most CSS type selectors must be changed into class selectors so it's possible to easily "borrow" the input style and calculate the width of its content. BREAKING CHANGE: Since CSS selectors must be changed, custom stylesheets based on the old selectors will conflict with this fix. They'll have to be updated to use class selectors. Closes #6. --- Gruntfile.js | 9 +++- css/autocomplete.css | 8 ++-- css/tags-input.css | 16 ++++---- karma.conf.js | 2 + src/autosize.js | 46 +++++++++++++++++++++ templates/auto-complete.html | 5 ++- templates/tags-input.html | 12 +++--- test/autosize.spec.js | 79 ++++++++++++++++++++++++++++++++++++ test/tags-input.spec.js | 8 ---- test/test-page.html | 13 +++++- 10 files changed, 168 insertions(+), 30 deletions(-) create mode 100644 src/autosize.js create mode 100644 test/autosize.spec.js diff --git a/Gruntfile.js b/Gruntfile.js index 69cbe829..124cb565 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -6,7 +6,14 @@ module.exports = function(grunt) { // Sets all files used by the script files: { js: { - src: ['src/keycodes.js', 'src/tags-input.js', 'src/auto-complete.js', 'src/transclude-append.js', 'src/configuration.js'], + src: [ + 'src/keycodes.js', + 'src/tags-input.js', + 'src/auto-complete.js', + 'src/transclude-append.js', + 'src/autosize.js', + 'src/configuration.js' + ], out: 'build/<%= pkg.name %>.js', outMin: 'tmp/<%= pkg.name %>.min.js' }, diff --git a/css/autocomplete.css b/css/autocomplete.css index 8828e131..8f35051b 100644 --- a/css/autocomplete.css +++ b/css/autocomplete.css @@ -11,13 +11,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; @@ -29,12 +29,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/css/tags-input.css b/css/tags-input.css index 30d1b0bd..8cc3c134 100644 --- a/css/tags-input.css +++ b/css/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; diff --git a/karma.conf.js b/karma.conf.js index ee61dac3..131d27be 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -17,10 +17,12 @@ module.exports = function(config) { 'test/tags-input.spec.js', 'test/auto-complete.spec.js', 'test/transclude-append.spec.js', + 'test/autosize.spec.js', 'src/keycodes.js', 'src/tags-input.js', 'src/auto-complete.js', 'src/transclude-append.js', + 'src/autosize.js', 'src/configuration.js', 'templates/*.html' ], diff --git a/src/autosize.js b/src/autosize.js new file mode 100644 index 00000000..16e27e97 --- /dev/null +++ b/src/autosize.js @@ -0,0 +1,46 @@ +'use strict'; + +/** + * @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); + } + }; +}); \ No newline at end of file diff --git a/templates/auto-complete.html b/templates/auto-complete.html index d852b47e..9a6cfbec 100644 --- a/templates/auto-complete.html +++ b/templates/auto-complete.html @@ -1,6 +1,7 @@
-