How to use the AutoComplete component (Starling version)
The AutoComplete
class extends the TextInput
component to add a pop-up list of suggestions as you type.
The Basics
First, let's create an AutoComplete
control and add it to the display list:
var input:AutoComplete = new AutoComplete();
this.addChild( input );
At this point, the AutoComplete
will behave like a normal TextInput
without suggestions. All properties available to a TextInput
(like maxChars
or prompt
, for example) may be used with an AutoComplete
too.
Provide completion suggestions
An IAutoCompleteSource
implementation should be passed to the source
property to display suggestions for completion. Let's look at a couple of the classes that we can use to provide these suggestions.
LocalAutoCompleteSource
The simplest option involves passing a collection, such as VectorCollection
, to LocalAutoCompleteSource
. As the user types, the collection will be filtered to display appropriate suggestions.
input.source = new LocalAutoCompleteSource( new VectorCollection(new <String>
[
"Apple",
"Banana",
"Cherry",
"Grape",
"Lemon",
"Orange",
"Watermelon"
]));
When one types "ap" into the AutoComplete
, the list of suggestions will include "Apple" and "Grape". By default, LocalAutoCompleteSource
converts each item to lowercase, and it returns any item that contains the entered text. The entered text may be in the middle of an item, as we see when "ap" matches "Grape".
If the default behavior doesn't quite fit our needs, we can use a custom compareFunction
to handle the filtering. In the following example, we create a compareFunction
where the entered text must be at the very beginning of the suggestion:
var source:LocalAutoCompleteSource = new LocalAutoCompleteSource();
source.compareFunction = function( item:Object, textToMatch:String ):Boolean
{
return item.toString().toLowerCase().indexOf(textToMatch.toLowerCase()) == 0;
};
In this case, if one types "ap" using the same data provider as in the previous example, only "Apple" will be suggested. "Grape" will not be suggested because "ap" appears in the middle of the word instead of the beginning.
As you can see above, the first argument to the compareFunction
is typed as Object
, meaning that suggestions don't necessarily need to be strings.
When using objects that aren't strings for suggestions, we must provide an implementation of the
toString()
function so that each suggestion can be converted to a string that the text input can display.
URLAutoCompleteSource
In some cases, you may want to request personalized suggestions from a server instead. We can pass the text entered by the user to a backend API using URLAutoCompleteSource
.
To load suggestions from the web, we need a URL. The urlRequestFunction
property can be used to generate a URLRequest
:
function createURLRequest( textToMatch:String ):URLRequest
{
var request:URLRequest = new URLRequest( "http://example.com/search_suggestions" );
var variables:URLVariables = new URLVariables();
variables.query = textToMatch;
request.data = variables;
return request;
};
input.source = new URLAutoCompleteSource( createURLRequest );
The urlRequestFunction
takes one argument, the text entered into the AutoComplete
. We can pass that to the server to return relevant suggestions.
By default, URLAutoCompleteSource
parses the result as a JSON array. If the result returned by the API looks similar to the example below, it can be parsed automatically:
[
"adobe",
"adobe flash",
"adobe reader",
"adobe creative cloud"
]
However, if the API returns data in a different format, we can use the parseResultFunction
property to tell the URLAutoCompleteSource
how to convert the result into something that the pop-up list of suggestions can display.
Let's create a parseResultFunction
for some XML in the following format:
<search>
<suggestion>adobe</suggestion>
<suggestion>adobe flash</suggestion>
<suggestion>adobe reader</suggestion>
<suggestion>adobe creative cloud</suggestion>
</search>
In the custom parseResultFunction
below, we loop through each <suggestion>
element in the result and extract the string. We'll return an Array
of these strings:
source.parseResultFunction = function( result:String ):Object
{
var parsedSuggestions:Array = [];
var xmlResult:XML = new XML( result );
var resultCount:int = xmlResult.suggestion.length();
for( var i:int = 0; i < resultCount; i++ )
{
var suggestion:XML = xmlResult.suggestion[i];
parsedSuggestions.push( suggestion.toString() );
}
return parsedSuggestions;
};
The parseResultFunction
may return an IListCollection
implementation, such as an ArrayCollection
or a VectorCollection
.
Customize suggestion behavior
The minimumAutoCompleteLength
property determines how many characters must be entered into the input before displaying suggestions:
input.minimumAutoCompleteLength = 3;
By default, the input will not make suggestions until at least 2
characters have been typed.
The autoCompleteDelay
property determines how long to wait after the text in the input has been edited before updating the suggestions:
input.autoCompleteDelay = 0.25;
This value is measured in seconds, and the default value is 0.5
.
Skinning an AutoComplete
As mentioned above, AutoComplete
is a subclass of TextInput
. For more detailed information about skins and font styles available to AutoComplete
, see How to use the TextInput
component. All styling properties are inherited by the AutoComplete
class.
Skinning the pop-up list
This section only explains how to access the pop-up list sub-component. Please read How to use the List
component for full details about the skinning properties that are available on List
components.
With a Theme
If you're creating a theme, you can target the AutoComplete.DEFAULT_CHILD_STYLE_NAME_LIST
style name.
getStyleProviderForClass( List )
.setFunctionForStyleName( AutoComplete.DEFAULT_CHILD_STYLE_NAME_LIST, setAutoCompleteListStyles );
The styling function might look like this:
private function setAutoCompleteListStyles( list:List ):void
{
list.backgroundSkin = new Image( listBackgroundTexture );
}
You can override the default style name to use a different one in your theme, if you prefer:
input.customListStyleName = "custom-list";
You can set the styling function for the customListStyleName
like this:
getStyleProviderForClass( List )
.setFunctionForStyleName( "custom-list", setAutoCompleteCustomListStyles );
Without a Theme
If you are not using a theme, you can use listFactory
to provide skins for the pop-up list
input.listFactory = function():List
{
var list:List = new List();
//skin the list here, if you're not using a theme
list.backgroundSkin = new Image( listBackgroundTexture );
return list;
}