Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

feat(autocomplete): Add promise support to md-item-text #2710

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/components/autocomplete/autocomplete.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ describe('<md-autocomplete>', function() {
ctrl.keydown({ keyCode: $mdConstant.KEY_CODE.DOWN_ARROW, preventDefault: angular.noop });
ctrl.keydown({ keyCode: $mdConstant.KEY_CODE.ENTER, preventDefault: angular.noop });
scope.$apply();
$timeout.flush();

expect(scope.searchText).toBe('foo');
expect(scope.selectedItem).toBe(scope.match(scope.searchText)[0]);
}));
Expand Down Expand Up @@ -96,6 +98,8 @@ describe('<md-autocomplete>', function() {
ctrl.keydown({ keyCode: $mdConstant.KEY_CODE.DOWN_ARROW, preventDefault: angular.noop });
ctrl.keydown({ keyCode: $mdConstant.KEY_CODE.ENTER, preventDefault: angular.noop });
scope.$apply();
$timeout.flush();

expect(scope.searchText).toBe('foo');
expect(scope.selectedItem).toBe(scope.match(scope.searchText)[0]);
}));
Expand Down Expand Up @@ -153,6 +157,7 @@ describe('<md-autocomplete>', function() {

ctrl.select(0);
element.scope().$apply();
$timeout.flush();

expect(scope.searchText).toBe('foo');
expect(scope.selectedItem).not.toBeNull();
Expand Down Expand Up @@ -196,6 +201,7 @@ describe('<md-autocomplete>', function() {

ctrl.select(0);
element.scope().$apply();
$timeout.flush();

expect(scope.itemChanged).toHaveBeenCalled();
expect(scope.itemChanged.calls.mostRecent().args[0].display).toBe('foo');
Expand Down
71 changes: 42 additions & 29 deletions src/components/autocomplete/js/autocompleteController.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var ITEM_HEIGHT = 41,
MENU_PADDING = 8;

function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $mdTheming, $window,
$animate, $rootElement, $attrs) {
$animate, $rootElement, $attrs, $q) {
//-- private variables
var ctrl = this,
itemParts = $scope.itemsExpr.split(/ in /i),
Expand Down Expand Up @@ -235,7 +235,9 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $
*/
function selectedItemChange (selectedItem, previousSelectedItem) {
if (selectedItem) {
$scope.searchText = getDisplayValue(selectedItem);
getDisplayValue(selectedItem).then(function(val) {
$scope.searchText = val;
});
}
if (angular.isFunction($scope.itemChange) && selectedItem !== previousSelectedItem)
$scope.itemChange(getItemScope(selectedItem));
Expand Down Expand Up @@ -283,21 +285,26 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $
ctrl.index = getDefaultIndex();
//-- do nothing on init
if (searchText === previousSearchText) return;
//-- clear selected item if search text no longer matches it
if (searchText !== getDisplayValue($scope.selectedItem)) $scope.selectedItem = null;
else return;
//-- trigger change event if available
if (angular.isFunction($scope.textChange) && searchText !== previousSearchText)
$scope.textChange(getItemScope($scope.selectedItem));
//-- cancel results if search text is not long enough
if (!isMinLengthMet()) {
ctrl.loading = false;
ctrl.matches = [];
ctrl.hidden = shouldHide();
updateMessages();
} else {
handleQuery();
}

getDisplayValue($scope.selectedItem).then(function(val) {
//-- clear selected item if search text no longer matches it
if (searchText !== val) $scope.selectedItem = null;
else return;

//-- trigger change event if available
if (angular.isFunction($scope.textChange) && searchText !== previousSearchText)
$scope.textChange(getItemScope($scope.selectedItem));
//-- cancel results if search text is not long enough
if (!isMinLengthMet()) {
ctrl.loading = false;
ctrl.matches = [];
ctrl.hidden = shouldHide();
updateMessages();
} else {
handleQuery();
}
});

}

/**
Expand Down Expand Up @@ -371,7 +378,7 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $
* @returns {*}
*/
function getDisplayValue (item) {
return (item && $scope.itemText) ? $scope.itemText(getItemScope(item)) : item;
return (item && $scope.itemText) ? $q.when($scope.itemText(getItemScope(item))) : $q.when(item);
}

/**
Expand Down Expand Up @@ -441,20 +448,24 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $
* Selects the item at the given index.
* @param index
*/
function select (index) {
$scope.selectedItem = ctrl.matches[index];
ctrl.loading = false;
ctrl.hidden = true;
ctrl.index = 0;
ctrl.matches = [];
function select(index) {
//-- force form to update state for validation
$timeout(function () {
elements.$.input.controller('ngModel').$setViewValue(getDisplayValue($scope.selectedItem) ||
$scope.searchText);
ctrl.hidden = true;
$timeout(function() {
getDisplayValue(ctrl.matches[index]).then(function(val) {
var ngModel = elements.$.input.controller('ngModel');
ngModel.$setViewValue(val);
ngModel.$render();
}).finally(function() {
$scope.selectedItem = ctrl.matches[index];
ctrl.loading = false;
ctrl.hidden = true;
ctrl.index = 0;
ctrl.matches = [];
});
});
}


/**
* Clears the searchText value and selected item.
*/
Expand Down Expand Up @@ -501,7 +512,9 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $
* Updates the ARIA messages
*/
function updateMessages () {
ctrl.messages = [ getCountMessage(), getCurrentDisplayValue() ];
getCurrentDisplayValue().then(function(msg) {
ctrl.messages = [ getCountMessage(), msg ];
});
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/components/autocomplete/js/autocompleteDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ function MdAutocomplete ($mdTheming, $mdUtil) {
class="md-visually-hidden"\
role="status"\
aria-live="assertive">\
<p ng-repeat="message in $mdAutocompleteCtrl.messages" ng-if="message">{{message}}</p>\
<p ng-repeat="message in $mdAutocompleteCtrl.messages track by $index" ng-if="message">{{message}}</p>\
</aria-status>';

function getItemTemplate() {
Expand Down
3 changes: 2 additions & 1 deletion src/components/chips/chips.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ describe('<md-chips>', function() {
element.scope().$apply(function() {
autocompleteCtrl.select(0);
});

$timeout.flush();

expect(scope.items.length).toBe(4);
expect(scope.items[3]).toBe('Kiwi');
}));
Expand Down