diff --git a/src/directives/autocomplete.coffee b/src/directives/autocomplete.coffee index c3c6053..5293076 100644 --- a/src/directives/autocomplete.coffee +++ b/src/directives/autocomplete.coffee @@ -11,7 +11,16 @@ A directive for providing suggestions while typing into the field @param {String} ng-model Assignable angular expression to data-bind to (required) @param {String} mac-placeholder Placeholder text @param {String} mac-autocomplete-url Url to fetch autocomplete dropdown list data. URL may include GET params e.g. "/users?nocache=1" -@param {Expression} mac-autocomplete-source Local data source +@param {Expression} mac-autocomplete-source Data to use. +Source support multiple types: +- Array: An array can be used for local data and there are two supported formats: + - An array of strings: ["Item1", "Item2"] + - An array of objects with mac-autocomplete-label key: [{name:"Item1"}, {name:"Item2"}] +- String: Using a string as the source is the same as passing the variable into mac-autocomplete-url +- Function: A callback when querying for data. The callback receive two arguments: + - {String} Value currently in the text input + - {Function} A response callback which expects a single argument, data to user. The data will be + populated on the menu and the menu will adjust accordingly @param {Boolean} mac-autocomplete-disabled Boolean value if autocomplete should be disabled @param {Function} mac-autocomplete-on-select Function called when user select on an item - `selected` - {Object} The item selected @@ -166,6 +175,32 @@ angular.module("Mac").directive "macAutocomplete", [ label = value = item[labelKey] or item $menuScope.items.push {label, value} + positionMenu() + + ### + @function + @name getData + @description + GET request to fetch data from server, update menu items and position + menu + @param {String} url URL to fetch data from + ### + getData = (url, query) -> + options = + method: "GET" + url: url + params: {} + options.params[queryKey] = query + + $http(options) + .success (data, status, headers, config) -> + dataList = onSuccess $scope, {data, status, headers} + dataList ?= data.data + + updateItem dataList + .error (data, status, headers, config) -> + onError $scope, {data, status, headers} + ### @function @name queryData @@ -177,24 +212,18 @@ angular.module("Mac").directive "macAutocomplete", [ url = autocompleteUrl $scope if url - options = - method: "GET" - url: url - params: {} - options.params[queryKey] = query - - $http(options) - .success (data, status, headers, config) -> - dataList = onSuccess $scope, {data, status, headers} - dataList ?= data.data - - updateItem dataList - positionMenu() - .error (data, status, headers, config) -> - onError $scope, {data, status, headers} - else if attrs.macAutocompleteSource? - updateItem $filter("filter")(source($scope), query) - positionMenu() + getData url, query + else + sourceData = source $scope + + if angular.isArray(sourceData) + updateItem $filter("filter")(sourceData, query) + + else if angular.isString(sourceData) + getData sourceData, query + + else if angular.isFunction(sourceData) + sourceData query, updateItem $menuScope.select = (index) -> selected = currentAutocomplete[index] diff --git a/test/unit/autocomplete.spec.coffee b/test/unit/autocomplete.spec.coffee index 2fea395..937a1b5 100644 --- a/test/unit/autocomplete.spec.coffee +++ b/test/unit/autocomplete.spec.coffee @@ -46,6 +46,11 @@ describe "Mac autocomplete", -> expect($(".mac-menu").length).toBe 0 describe "source", -> + $httpBackend = null + + beforeEach inject (_$httpBackend_) -> + $httpBackend = _$httpBackend_ + it "should use local array", -> $rootScope.source = data $rootScope.test = "" @@ -69,6 +74,30 @@ describe "Mac autocomplete", -> changeInputValue element, "f" expect($(".mac-menu-item").text() == "foo").toBe true + it "should use a url string and work exactly like mac-autocomplete-url", -> + $httpBackend.when("GET", "/api/autocomplete?q=f").respond({data}) + + $rootScope.source = "/api/autocomplete" + + element = $compile("") $rootScope + $rootScope.$digest() + + changeInputValue element, "f" + $rootScope.$digest() + + $httpBackend.flush() + + it "should use a callback function", -> + $rootScope.source = (query, callback) -> callback ["foo"] + + element = $compile("") $rootScope + $rootScope.$digest() + + changeInputValue element, "f" + $rootScope.$digest() + + expect($(".mac-menu-item").text() == "foo").toBe true + describe "label", -> it "should use default 'name' label", -> $rootScope.source = [