From 3b766479219c3c89ed4c4f6f0545bbdf78befb97 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 5 Feb 2016 19:57:24 +0100 Subject: [PATCH] fix(autocomplete): fix not found template detection when element is hidden When the element is hidden at compilation time through a ng-if directive for example. The stored variable as currently used will be trashed, so it will be undefined. So there a possibilities to store that state, using a variable in the directive (ex. hashmaps with ids) or storing it as an attribute / class. Fixes #7035 Fixes #7142 Closes #7042 --- .../autocomplete/autocomplete.spec.js | 27 +++++++++++++++++++ .../autocomplete/js/autocompleteDirective.js | 11 +++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/components/autocomplete/autocomplete.spec.js b/src/components/autocomplete/autocomplete.spec.js index 2665d6d1537..5e3cda228c3 100644 --- a/src/components/autocomplete/autocomplete.spec.js +++ b/src/components/autocomplete/autocomplete.spec.js @@ -488,6 +488,33 @@ describe('', function() { element.remove(); })); + it('properly sets hasNotFound when element is hidden through ng-if', inject(function() { + var scope = createScope(); + var template1 = + '
' + + '' + + '{{item.display}}' + + 'Sorry, not found...' + + '' + + '
'; + var element = compile(template1, scope); + var ctrl = element.children().controller('mdAutocomplete'); + + expect(ctrl).toBeUndefined(); + + scope.$apply('showAutocomplete = true'); + + ctrl = element.children().controller('mdAutocomplete'); + + expect(ctrl.hasNotFound).toBe(true); + })); + it('properly sets hasNotFound with multiple autocompletes', inject(function($timeout, $material) { var scope = createScope(); var template1 = diff --git a/src/components/autocomplete/js/autocompleteDirective.js b/src/components/autocomplete/js/autocompleteDirective.js index a2c11cabd99..8a1ea72992e 100644 --- a/src/components/autocomplete/js/autocompleteDirective.js +++ b/src/components/autocomplete/js/autocompleteDirective.js @@ -146,8 +146,9 @@ function MdAutocomplete () { inputId: '@?mdInputId' }, link: function(scope, element, attrs, controller) { - controller.hasNotFound = element.hasNotFoundTemplate; - delete element.hasNotFoundTemplate; + // Retrieve the state of using a md-not-found template by using our attribute, which will + // be added to the element in the template function. + controller.hasNotFound = !!element.attr('md-has-not-found'); }, template: function (element, attr) { var noItemsTemplate = getNoItemsTemplate(), @@ -155,8 +156,10 @@ function MdAutocomplete () { leftover = element.html(), tabindex = attr.tabindex; - // Set our variable for the link function above which runs later - element.hasNotFoundTemplate = !!noItemsTemplate; + // Set our attribute for the link function above which runs later. + // We will set an attribute, because otherwise the stored variables will be trashed when + // removing the element is hidden while retrieving the template. For example when using ngIf. + if (noItemsTemplate) element.attr('md-has-not-found', true); if (!attr.hasOwnProperty('tabindex')) element.attr('tabindex', '-1');