3

I am using a Angular md-autocomplete which starts showing users the auto completion options in a drop-down after they first type in the text box. Is there anyway to have this dropdown shown when the user first clicks in the text box as well?

Here is the md-autocomplete html:

<md-autocomplete flex
                 role="combobox"
                 md-selected-item="text"
                 md-no-cache="true"
                 md-search-text="searchText"
                 md-search-text-change="searchTextChange(searchText)"
                 md-items="item in getMatches(searchText)"
                 md-item-text="item.autocompleteVal"
                 md-min-length="0"
                 md-selected-item-change="$parent.selectedItemChange(item)" on-enter ng-cloak>
                            <span id="autocompleteText" md-highlight-text="searchText" md-highlight-flags="^i">{{item.autocompleteVal}} </span>
</md-autocomplete>
Nick
  • 1,743
  • 6
  • 23
  • 38
  • 1
    What would you want to show in the drop down when it opens? – mindparse Sep 09 '16 at 20:38
  • Try github.com/tnr2394/autoCompleteTextbox.. It provides a lot of customization. – Tirthraj Barot Sep 09 '16 at 20:39
  • @midparse, the autocomplete is filled with context before the user takes any action. When the user clicks in the autocomplete, I would like to show results based on what is already in the text box. – Nick Sep 09 '16 at 20:41
  • But in your question you are asking if there is a way to show the dropdown on first click, otherwise the dropdown will show as the user types. At the moment of first click the textbox will be empty. Am I right? – ocespedes Sep 09 '16 at 21:16
  • @ocespedes The textbox will not be empty when the user first clicks in the textbox. There is already some text present in the text box. – Nick Sep 09 '16 at 21:24
  • It seems to work okay clicking in the input - http://codepen.io/camden-kid/pen/mAZrAQ?editors=1010 – camden_kid Sep 10 '16 at 10:10

5 Answers5

7

I was having same issue but setting the value of md-min-length to zero starts working

md-min-length="0"

Update: If it still does not work then make sure that the searchTerm is initially set to null

Controller

vm.searchTerm = null

Html:

md-search-text="vm.searchTerm"
Emmad Zahid
  • 438
  • 6
  • 15
6

As @Hodglem pointed out, the current Material docs use the valueChanges observable of the FormControl object to detect changes and filter the options to display on the autocomplete panel. They prime the initial value as "null" so that all the available options will display.

However, often your list of options comes from a service (as in my use case) and your list is empty when startsWith(null) runs, especially if this code is in the ngOnInit() method like it is in the Material docs. This method runs immediately, while the service takes time to fill the list.

Autocomplete is smart enough to not open the panel if there are no options, so the initial focus on the element will not open the panel since there are no options to display. Even after the list fills from the service, the filter only gets triggered with a change in value on the control, so until the user starts typing, autocomplete's list of options remains empty, and therefore the panel remains closed.

I have two solutions:

  1. Move the observable set up out of the ngOnInit() method, and into the subscribe() method that follows the call to the service that retrieves the options. After setting the list, run the observable set up. Now the panel will open on focus since the panel has options to display. (Make sure that the initialization of the FormControl remains in the ngOnInit() method, or the binding in the template will throw an error.)

  2. Scratch the observable approach, and bind the filter method to the control's native events, such as (focus) and (input). In the filter method, check if the passed-in value is null or empty, and if it is, return the entire list. This way, the filter gets triggered every time the user clicks on the control or changes its value, and as long as the user clicks on the control at least once after the service filled the list of options, the panel will display. Depending on your use case, I found that by the time the user moves the mouse and focuses on the control, the service already delivered the goods, and the panel opens.

Paul Roub
  • 36,322
  • 27
  • 84
  • 93
andreisrob
  • 1,615
  • 15
  • 11
2

Seems like demo from site works as you expected. https://material.angularjs.org/latest/demo/autocomplete

Valery Kozlov
  • 1,557
  • 2
  • 11
  • 19
2

For Angular 2 and Material 2, setting startWith() on the valueChanges() observable of the control to null will show all of the values. Omitting this will result in the user first needing to type a value in to see results.

All values displayed on focus:

this.filterFuelTypeObservers.push(newFormGroup.controls.fuelType.valueChanges
    .startWith(null)
    .map(value => value ? this.fuelTypeFilter(value) : this.fuelTypes));

No values displayed until entry:

this.filterFuelTypeObservers.push(newFormGroup.controls.fuelType.valueChanges
    .map(value => value ? this.fuelTypeFilter(value) : this.fuelTypes));

I haven't, but I imagine you could play around with startWith() to set the on focus list to be filtered by something also.

Hodglem
  • 614
  • 9
  • 17
0

Just add the following line

md-min-length="0"

This will trigger a md-items calls even when just clicked

Anand Kadhi
  • 1,790
  • 4
  • 27
  • 40