From b93d17b1393ec935027e5a948956b5f073d73ce2 Mon Sep 17 00:00:00 2001 From: Adrian Lee Date: Wed, 16 Oct 2013 16:09:48 -0700 Subject: [PATCH] refactor(macAutocomplete): Updated autocomplete to not append menu initially. Menu is appended to body when needed. Menu will not show up when there is no input or after selecting and item. Menu will be removed when scope is destroyed. --- src/directives/autocomplete.coffee | 76 ++++++++++++++++++++---------- test/unit/autocomplete.spec.coffee | 6 +++ 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/src/directives/autocomplete.coffee b/src/directives/autocomplete.coffee index 93c6238..3abe755 100644 --- a/src/directives/autocomplete.coffee +++ b/src/directives/autocomplete.coffee @@ -57,13 +57,25 @@ angular.module("Mac").directive "macAutocomplete", [ currentAutocomplete = [] timeoutId = null + onSelectBool = false $menuScope = $rootScope.$new() $menuScope.items = [] $menuScope.index = 0 + menuEl = angular.element("") + menuEl.attr + "mac-menu-items": "items" + "mac-menu-style": "style" + "mac-menu-select": "select(index)" + "mac-menu-index": "index" + # Precompile menu element + $compile(menuEl) $menuScope + ctrl.$parsers.push (value) -> - if value and not disabled($scope) + # If value is more than an empty string, + # autocomplete is enabled and not 'onSelect' cycle + if value and not disabled($scope) and not onSelectBool if delay > 0 $timeout.cancel timeoutId if timeoutId? timeoutId = $timeout -> @@ -71,9 +83,25 @@ angular.module("Mac").directive "macAutocomplete", [ , delay else queryData value + else + reset() + + onSelectBool = false return value + # + # @function + # @name appendMenu + # @description + # Adding menu to DOM + # + appendMenu = -> + if inside + element.after menuEl + else + angular.element(document.body).append menuEl + # # @function # @name reset @@ -83,6 +111,7 @@ angular.module("Mac").directive "macAutocomplete", [ reset = -> $menuScope.items = [] $menuScope.index = 0 + menuEl.remove() # # @function @@ -91,14 +120,17 @@ angular.module("Mac").directive "macAutocomplete", [ # Calculate the style include position and width for menu # positionMenu = -> - $menuScope.style = element.offset() - $menuScope.style.top += element.outerHeight() - $menuScope.style.width = element.outerWidth() + if $menuScope.items.length > 0 + $menuScope.style = element.offset() + $menuScope.style.top += element.outerHeight() + $menuScope.style.width = element.outerWidth() + + angular.forEach $menuScope.style, (value, key) -> + if not isNaN(+value) and angular.isNumber +value + value = "#{value}px" + $menuScope.style[key] = value - angular.forEach $menuScope.style, (value, key) -> - if not isNaN(+value) and angular.isNumber +value - value = "#{value}px" - $menuScope.style[key] = value + appendMenu() # # @function @@ -108,11 +140,12 @@ angular.module("Mac").directive "macAutocomplete", [ # @param {Array} data Array of data # updateItem = (data = []) -> - currentAutocomplete = data - $menuScope.items = [] - for item in data - label = value = item[labelKey] or item - $menuScope.items.push {label, value} + if data.length > 0 + currentAutocomplete = data + $menuScope.items = [] + for item in data + label = value = item[labelKey] or item + $menuScope.items.push {label, value} # # @function @@ -148,7 +181,9 @@ angular.module("Mac").directive "macAutocomplete", [ selected = currentAutocomplete[index] onSelect $scope, {selected} - label = $menuScope.items[index].label or "" + label = $menuScope.items[index].label or "" + onSelectBool = true + if attrs.ngModel? ctrl.$setViewValue label ctrl.$render() @@ -176,16 +211,9 @@ angular.module("Mac").directive "macAutocomplete", [ if $menuScope.items.length > 0 $scope.$apply -> reset() - menuEl = angular.element("") - menuEl.attr - "mac-menu-items": "items" - "mac-menu-style": "style" - "mac-menu-select": "select(index)" - "mac-menu-index": "index" - if inside - element.after $compile(menuEl) $menuScope - else - angular.element(document.body).append $compile(menuEl) $menuScope + $scope.$on "$destroy", -> + # Remove menu on body when autocomplete is removed + menuEl.remove() # # @event diff --git a/test/unit/autocomplete.spec.coffee b/test/unit/autocomplete.spec.coffee index 0a85ed8..2fea395 100644 --- a/test/unit/autocomplete.spec.coffee +++ b/test/unit/autocomplete.spec.coffee @@ -39,6 +39,12 @@ describe "Mac autocomplete", -> expect(init).toThrow() + it "should not append menu", -> + element = $compile("") $rootScope + $rootScope.$digest() + + expect($(".mac-menu").length).toBe 0 + describe "source", -> it "should use local array", -> $rootScope.source = data