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

Commit dadbcf2

Browse files
devversionThomasBurleson
authored andcommitted
fix(autocomplete): clear search text if select item cleared.
* Currently the autocomplete always updates the searchText according the changed selectedItem. * When the selectedItem was manually cleared, the searchText will be not updated. * The `searchText` should be cleared, when the `selectedItem` was cleared and the searchText still matches the selectedItem Fixes #8788. Closes #9087
1 parent a119646 commit dadbcf2

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

src/components/autocomplete/autocomplete.spec.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ describe('<md-autocomplete>', function() {
5858
}
5959

6060
describe('basic functionality', function() {
61+
6162
it('updates selected item and search text', inject(function($timeout, $mdConstant, $material) {
6263
var scope = createScope();
6364
var template = '\
@@ -103,6 +104,116 @@ describe('<md-autocomplete>', function() {
103104
element.remove();
104105
}));
105106

107+
it('should clear the searchText when the selectedItem manually got cleared',
108+
inject(function($timeout, $material, $mdConstant) {
109+
var scope = createScope();
110+
111+
var template =
112+
'<md-autocomplete ' +
113+
'md-selected-item="selectedItem" ' +
114+
'md-search-text="searchText" ' +
115+
'md-items="item in match(searchText)" ' +
116+
'md-item-text="item.display" ' +
117+
'placeholder="placeholder"> ' +
118+
'<span md-highlight-text="searchText">{{item.display}}</span>' +
119+
'</md-autocomplete>';
120+
121+
var element = compile(template, scope);
122+
var ctrl = element.controller('mdAutocomplete');
123+
var ul = element.find('ul');
124+
125+
$material.flushInterimElement();
126+
127+
expect(scope.searchText).toBe('');
128+
expect(scope.selectedItem).toBe(null);
129+
130+
ctrl.focus();
131+
132+
scope.$apply('searchText = "fo"');
133+
waitForVirtualRepeat(element);
134+
135+
expect(scope.searchText).toBe('fo');
136+
expect(scope.match(scope.searchText).length).toBe(1);
137+
138+
expect(ul.find('li').length).toBe(1);
139+
140+
// Run our key events to trigger a select action
141+
ctrl.keydown(keydownEvent($mdConstant.KEY_CODE.DOWN_ARROW));
142+
ctrl.keydown(keydownEvent($mdConstant.KEY_CODE.ENTER));
143+
$timeout.flush();
144+
145+
expect(scope.searchText).toBe('foo');
146+
expect(scope.selectedItem).toBe(scope.match(scope.searchText)[0]);
147+
148+
// Reset / Clear the current selected item.
149+
scope.$apply('selectedItem = null');
150+
waitForVirtualRepeat(element);
151+
152+
// Run our key events to trigger a select action
153+
ctrl.keydown(keydownEvent($mdConstant.KEY_CODE.DOWN_ARROW));
154+
ctrl.keydown(keydownEvent($mdConstant.KEY_CODE.ENTER));
155+
$timeout.flush();
156+
157+
// The autocomplete automatically clears the searchText when the selectedItem was cleared.
158+
expect(scope.searchText).toBe('');
159+
expect(scope.selectedItem).toBeFalsy();
160+
161+
element.remove();
162+
}));
163+
164+
it('should should not clear the searchText when clearing the selected item from the input',
165+
inject(function($timeout, $material, $mdConstant) {
166+
var scope = createScope();
167+
168+
var template =
169+
'<md-autocomplete ' +
170+
'md-selected-item="selectedItem" ' +
171+
'md-search-text="searchText" ' +
172+
'md-items="item in match(searchText)" ' +
173+
'md-item-text="item.display" ' +
174+
'placeholder="placeholder"> ' +
175+
'<span md-highlight-text="searchText">{{item.display}}</span>' +
176+
'</md-autocomplete>';
177+
178+
var element = compile(template, scope);
179+
var ctrl = element.controller('mdAutocomplete');
180+
var input = element.find('input');
181+
var ul = element.find('ul');
182+
183+
$material.flushInterimElement();
184+
185+
expect(scope.searchText).toBe('');
186+
expect(scope.selectedItem).toBe(null);
187+
188+
ctrl.focus();
189+
190+
scope.$apply('searchText = "fo"');
191+
waitForVirtualRepeat(element);
192+
193+
expect(scope.searchText).toBe('fo');
194+
expect(scope.match(scope.searchText).length).toBe(1);
195+
196+
expect(ul.find('li').length).toBe(1);
197+
198+
// Run our key events to trigger a select action
199+
ctrl.keydown(keydownEvent($mdConstant.KEY_CODE.DOWN_ARROW));
200+
ctrl.keydown(keydownEvent($mdConstant.KEY_CODE.ENTER));
201+
$timeout.flush();
202+
203+
expect(scope.searchText).toBe('foo');
204+
expect(scope.selectedItem).toBe(scope.match(scope.searchText)[0]);
205+
206+
scope.$apply('searchText = "food"');
207+
208+
$timeout.flush();
209+
210+
// The autocomplete automatically clears the searchText when the selectedItem was cleared.
211+
expect(scope.searchText).toBe('food');
212+
expect(scope.selectedItem).toBeFalsy();
213+
214+
element.remove();
215+
}));
216+
106217
it('allows you to set an input id without floating label', inject(function() {
107218
var scope = createScope(null, {inputId: 'custom-input-id'});
108219
var template = '\

src/components/autocomplete/js/autocompleteController.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,15 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
328328
$scope.searchText = val;
329329
handleSelectedItemChange(selectedItem, previousSelectedItem);
330330
});
331+
} else if (previousSelectedItem) {
332+
getDisplayValue(previousSelectedItem).then(function(displayValue) {
333+
// Clear the searchText, when the selectedItem is set to null.
334+
// Do not clear the searchText, when the searchText isn't matching with the previous
335+
// selected item.
336+
if (displayValue.toLowerCase() === $scope.searchText.toLowerCase()) {
337+
$scope.searchText = '';
338+
}
339+
});
331340
}
332341

333342
if (selectedItem !== previousSelectedItem) announceItemChange();

0 commit comments

Comments
 (0)