From ec8d912217b020e3eda93cc282fbfbe55671dde0 Mon Sep 17 00:00:00 2001 From: Andrei Horodinca Date: Wed, 13 Sep 2017 10:00:28 +0200 Subject: [PATCH 1/4] chore: do not calculate the search input width anymore --- src/uiSelectController.js | 47 -------------------------------- src/uiSelectMatchDirective.js | 7 +---- src/uiSelectMultipleDirective.js | 9 ------ test/select.spec.js | 38 -------------------------- 4 files changed, 1 insertion(+), 100 deletions(-) diff --git a/src/uiSelectController.js b/src/uiSelectController.js index a92b94d2a..abb59b4f1 100644 --- a/src/uiSelectController.js +++ b/src/uiSelectController.js @@ -528,46 +528,6 @@ uis.controller('uiSelectCtrl', }; } - - var sizeWatch = null; - var updaterScheduled = false; - ctrl.sizeSearchInput = function() { - - var input = ctrl.searchInput[0], - container = ctrl.$element[0], - calculateContainerWidth = function() { - // Return the container width only if the search input is visible - return container.clientWidth * !!input.offsetParent; - }, - updateIfVisible = function(containerWidth) { - if (containerWidth === 0) { - return false; - } - var inputWidth = containerWidth - input.offsetLeft; - if (inputWidth < 50) inputWidth = containerWidth; - ctrl.searchInput.css('width', inputWidth+'px'); - return true; - }; - - ctrl.searchInput.css('width', '10px'); - $timeout(function() { //Give tags time to render correctly - if (sizeWatch === null && !updateIfVisible(calculateContainerWidth())) { - sizeWatch = $scope.$watch(function() { - if (!updaterScheduled) { - updaterScheduled = true; - $scope.$$postDigest(function() { - updaterScheduled = false; - if (updateIfVisible(calculateContainerWidth())) { - sizeWatch(); - sizeWatch = null; - } - }); - } - }, angular.noop); - } - }); - }; - function _handleDropDownSelection(key) { var processed = true; switch (key) { @@ -740,15 +700,8 @@ uis.controller('uiSelectCtrl', } } - var onResize = $$uisDebounce(function() { - ctrl.sizeSearchInput(); - }, 50); - - angular.element($window).bind('resize', onResize); - $scope.$on('$destroy', function() { ctrl.searchInput.off('keyup keydown tagged blur paste'); - angular.element($window).off('resize', onResize); }); $scope.$watch('$select.activeIndex', function(activeIndex) { diff --git a/src/uiSelectMatchDirective.js b/src/uiSelectMatchDirective.js index ef9bdcf33..191862095 100644 --- a/src/uiSelectMatchDirective.js +++ b/src/uiSelectMatchDirective.js @@ -13,7 +13,7 @@ uis.directive('uiSelectMatch', ['uiSelectConfig', function(uiSelectConfig) { var theme = getAttribute(parent, 'theme') || uiSelectConfig.theme; var multi = angular.isDefined(getAttribute(parent, 'multiple')); - return theme + (multi ? '/match-multiple.tpl.html' : '/match.tpl.html'); + return theme + (multi ? '/match-multiple.tpl.html' : '/match.tpl.html'); }, link: function(scope, element, attrs, $select) { $select.lockChoiceExpression = attrs.uiLockChoice; @@ -27,11 +27,6 @@ uis.directive('uiSelectMatch', ['uiSelectConfig', function(uiSelectConfig) { attrs.$observe('allowClear', setAllowClear); setAllowClear(attrs.allowClear); - - if($select.multiple){ - $select.sizeSearchInput(); - } - } }; diff --git a/src/uiSelectMultipleDirective.js b/src/uiSelectMultipleDirective.js index 06de4f134..a45846db3 100644 --- a/src/uiSelectMultipleDirective.js +++ b/src/uiSelectMultipleDirective.js @@ -29,9 +29,6 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec if($select.refreshItems){ $select.refreshItems(); } - if($select.sizeSearchInput){ - $select.sizeSearchInput(); - } }; // Remove item from multiple select @@ -47,7 +44,6 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec $select.selected.splice(index, 1); ctrl.activeMatchIndex = -1; - $select.sizeSearchInput(); // Give some time for scope propagation. $timeout(function(){ @@ -188,11 +184,6 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec $selectMultiple.activeMatchIndex = -1; }); - scope.$watch('$select.disabled', function(newValue, oldValue) { - // As the search input field may now become visible, it may be necessary to recompute its size - if (oldValue && !newValue) $select.sizeSearchInput(); - }); - $select.searchInput.on('keydown', function(e) { var key = e.which; scope.$apply(function() { diff --git a/test/select.spec.js b/test/select.spec.js index 7f6f6a98f..8f08335ed 100644 --- a/test/select.spec.js +++ b/test/select.spec.js @@ -2046,44 +2046,6 @@ describe('ui-select tests', function () { expect($(el).attr('tabindex')).toEqual(undefined); }); - it('should update size of search input after removing an item', function () { - scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; //Wladimir & Samantha - var el = createUiSelectMultiple(); - - spyOn(el.scope().$select, 'sizeSearchInput'); - - var searchInput = el.find('.ui-select-search'); - var oldWidth = searchInput.css('width'); - - el.find('.ui-select-match-item').first().find('.ui-select-match-close').click(); - expect(el.scope().$select.sizeSearchInput).toHaveBeenCalled(); - - }); - - it('should update size of search input use container width', function () { - scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; //Wladimir & Samantha - var el = createUiSelectMultiple({ - appendToBody: true - }); - - angular.element(document.body).css("width", "100%"); - angular.element(document.body).css("height", "100%"); - angular.element(document.body).append(el); - - spyOn(el.scope().$select, 'sizeSearchInput'); - - var searchInput = el.find('.ui-select-search'); - el.find('.ui-select-match-item').first().find('.ui-select-match-close').click(); - - expect(el.scope().$select.sizeSearchInput).toHaveBeenCalled(); - - $timeout.flush(); - - var newWidth = searchInput[0].clientWidth + searchInput[0].offsetLeft; - var containerWidth = el[0].clientWidth; - expect(containerWidth - newWidth).toBeLessThan(10); - - }); it('should move to last match when pressing BACKSPACE key from search', function () { var el = createUiSelectMultiple(); From ae43631aa545348bb6e2e41e4afacfaff492964b Mon Sep 17 00:00:00 2001 From: Andrei Horodinca Date: Wed, 13 Sep 2017 10:02:22 +0200 Subject: [PATCH 2/4] feat: wrap ui-select-match in label to allow clicking anywhere to search --- src/bootstrap/match-multiple.tpl.html | 2 +- src/bootstrap/select-multiple.tpl.html | 4 ++-- src/common.css | 6 ++++++ src/uiSelectMultipleDirective.js | 6 +++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/match-multiple.tpl.html b/src/bootstrap/match-multiple.tpl.html index be9e92da7..20e584367 100644 --- a/src/bootstrap/match-multiple.tpl.html +++ b/src/bootstrap/match-multiple.tpl.html @@ -8,7 +8,7 @@ ng-click="$selectMultiple.activeMatchIndex = $index;" ng-class="{'btn-primary':$selectMultiple.activeMatchIndex === $index, 'select-locked':$select.isLocked(this, $index)}" ui-select-sort="$select.selected"> -  × +  × diff --git a/src/bootstrap/select-multiple.tpl.html b/src/bootstrap/select-multiple.tpl.html index db932255b..92a21cbb9 100644 --- a/src/bootstrap/select-multiple.tpl.html +++ b/src/bootstrap/select-multiple.tpl.html @@ -1,5 +1,5 @@ diff --git a/src/common.css b/src/common.css index c81d540c7..8835e0ef5 100644 --- a/src/common.css +++ b/src/common.css @@ -352,3 +352,9 @@ body > .ui-select-bootstrap.open { .ui-select-refreshing.ng-animate { -webkit-animation: none 0s; } + +/* ui-select-multiple search wrapper */ +.ui-select-search-wrapper { + display: block; + cursor: text; +} \ No newline at end of file diff --git a/src/uiSelectMultipleDirective.js b/src/uiSelectMultipleDirective.js index a45846db3..360b9836a 100644 --- a/src/uiSelectMultipleDirective.js +++ b/src/uiSelectMultipleDirective.js @@ -32,7 +32,11 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec }; // Remove item from multiple select - ctrl.removeChoice = function(index){ + ctrl.removeChoice = function(index, event){ + // do not open the results dropdown + if(event) { + event.stopPropagation(); + } // if the choice is locked, don't remove it if($select.isLocked(null, index)) return false; From 74c94373f4da2482e87a675320cd5b87b264193e Mon Sep 17 00:00:00 2001 From: Andrei Horodinca Date: Wed, 13 Sep 2017 10:18:23 +0200 Subject: [PATCH 3/4] style: reset label styles --- src/common.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common.css b/src/common.css index 8835e0ef5..f0a6201d7 100644 --- a/src/common.css +++ b/src/common.css @@ -356,5 +356,7 @@ body > .ui-select-bootstrap.open { /* ui-select-multiple search wrapper */ .ui-select-search-wrapper { display: block; + margin: 0; cursor: text; + font-weight: normal; } \ No newline at end of file From 03bb34b1b0b8b444663fe647aeab804f3af067c8 Mon Sep 17 00:00:00 2001 From: Andrei Horodinca Date: Wed, 13 Sep 2017 10:43:20 +0200 Subject: [PATCH 4/4] Revert "chore: do not calculate the search input width anymore" This reverts commit ec8d912217b020e3eda93cc282fbfbe55671dde0. --- src/uiSelectController.js | 47 ++++++++++++++++++++++++++++++++ src/uiSelectMatchDirective.js | 7 ++++- src/uiSelectMultipleDirective.js | 9 ++++++ test/select.spec.js | 38 ++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/uiSelectController.js b/src/uiSelectController.js index abb59b4f1..a92b94d2a 100644 --- a/src/uiSelectController.js +++ b/src/uiSelectController.js @@ -528,6 +528,46 @@ uis.controller('uiSelectCtrl', }; } + + var sizeWatch = null; + var updaterScheduled = false; + ctrl.sizeSearchInput = function() { + + var input = ctrl.searchInput[0], + container = ctrl.$element[0], + calculateContainerWidth = function() { + // Return the container width only if the search input is visible + return container.clientWidth * !!input.offsetParent; + }, + updateIfVisible = function(containerWidth) { + if (containerWidth === 0) { + return false; + } + var inputWidth = containerWidth - input.offsetLeft; + if (inputWidth < 50) inputWidth = containerWidth; + ctrl.searchInput.css('width', inputWidth+'px'); + return true; + }; + + ctrl.searchInput.css('width', '10px'); + $timeout(function() { //Give tags time to render correctly + if (sizeWatch === null && !updateIfVisible(calculateContainerWidth())) { + sizeWatch = $scope.$watch(function() { + if (!updaterScheduled) { + updaterScheduled = true; + $scope.$$postDigest(function() { + updaterScheduled = false; + if (updateIfVisible(calculateContainerWidth())) { + sizeWatch(); + sizeWatch = null; + } + }); + } + }, angular.noop); + } + }); + }; + function _handleDropDownSelection(key) { var processed = true; switch (key) { @@ -700,8 +740,15 @@ uis.controller('uiSelectCtrl', } } + var onResize = $$uisDebounce(function() { + ctrl.sizeSearchInput(); + }, 50); + + angular.element($window).bind('resize', onResize); + $scope.$on('$destroy', function() { ctrl.searchInput.off('keyup keydown tagged blur paste'); + angular.element($window).off('resize', onResize); }); $scope.$watch('$select.activeIndex', function(activeIndex) { diff --git a/src/uiSelectMatchDirective.js b/src/uiSelectMatchDirective.js index 191862095..ef9bdcf33 100644 --- a/src/uiSelectMatchDirective.js +++ b/src/uiSelectMatchDirective.js @@ -13,7 +13,7 @@ uis.directive('uiSelectMatch', ['uiSelectConfig', function(uiSelectConfig) { var theme = getAttribute(parent, 'theme') || uiSelectConfig.theme; var multi = angular.isDefined(getAttribute(parent, 'multiple')); - return theme + (multi ? '/match-multiple.tpl.html' : '/match.tpl.html'); + return theme + (multi ? '/match-multiple.tpl.html' : '/match.tpl.html'); }, link: function(scope, element, attrs, $select) { $select.lockChoiceExpression = attrs.uiLockChoice; @@ -27,6 +27,11 @@ uis.directive('uiSelectMatch', ['uiSelectConfig', function(uiSelectConfig) { attrs.$observe('allowClear', setAllowClear); setAllowClear(attrs.allowClear); + + if($select.multiple){ + $select.sizeSearchInput(); + } + } }; diff --git a/src/uiSelectMultipleDirective.js b/src/uiSelectMultipleDirective.js index 360b9836a..819e55e5a 100644 --- a/src/uiSelectMultipleDirective.js +++ b/src/uiSelectMultipleDirective.js @@ -29,6 +29,9 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec if($select.refreshItems){ $select.refreshItems(); } + if($select.sizeSearchInput){ + $select.sizeSearchInput(); + } }; // Remove item from multiple select @@ -48,6 +51,7 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec $select.selected.splice(index, 1); ctrl.activeMatchIndex = -1; + $select.sizeSearchInput(); // Give some time for scope propagation. $timeout(function(){ @@ -188,6 +192,11 @@ uis.directive('uiSelectMultiple', ['uiSelectMinErr','$timeout', function(uiSelec $selectMultiple.activeMatchIndex = -1; }); + scope.$watch('$select.disabled', function(newValue, oldValue) { + // As the search input field may now become visible, it may be necessary to recompute its size + if (oldValue && !newValue) $select.sizeSearchInput(); + }); + $select.searchInput.on('keydown', function(e) { var key = e.which; scope.$apply(function() { diff --git a/test/select.spec.js b/test/select.spec.js index 8f08335ed..7f6f6a98f 100644 --- a/test/select.spec.js +++ b/test/select.spec.js @@ -2046,6 +2046,44 @@ describe('ui-select tests', function () { expect($(el).attr('tabindex')).toEqual(undefined); }); + it('should update size of search input after removing an item', function () { + scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; //Wladimir & Samantha + var el = createUiSelectMultiple(); + + spyOn(el.scope().$select, 'sizeSearchInput'); + + var searchInput = el.find('.ui-select-search'); + var oldWidth = searchInput.css('width'); + + el.find('.ui-select-match-item').first().find('.ui-select-match-close').click(); + expect(el.scope().$select.sizeSearchInput).toHaveBeenCalled(); + + }); + + it('should update size of search input use container width', function () { + scope.selection.selectedMultiple = [scope.people[4], scope.people[5]]; //Wladimir & Samantha + var el = createUiSelectMultiple({ + appendToBody: true + }); + + angular.element(document.body).css("width", "100%"); + angular.element(document.body).css("height", "100%"); + angular.element(document.body).append(el); + + spyOn(el.scope().$select, 'sizeSearchInput'); + + var searchInput = el.find('.ui-select-search'); + el.find('.ui-select-match-item').first().find('.ui-select-match-close').click(); + + expect(el.scope().$select.sizeSearchInput).toHaveBeenCalled(); + + $timeout.flush(); + + var newWidth = searchInput[0].clientWidth + searchInput[0].offsetLeft; + var containerWidth = el[0].clientWidth; + expect(containerWidth - newWidth).toBeLessThan(10); + + }); it('should move to last match when pressing BACKSPACE key from search', function () { var el = createUiSelectMultiple();