Autocomplete
It is becoming increasingly common for apps to offer predictive suggestions as the user types in a text input field. One example of this is a search field suggesting results that match the text that the user has already typed.
The Autocomplete
component extends the native input
control, and inherits all its capabilities, such as data binding support for all writable attributes of the input
element. It adds the capability to define a list of values that will be contextually displayed as suggestions based on the search term. As the user types the search results are updated to reflect the new term.
Using the Autocomplete
Component
Autocomplete
component can be found in matte. You first need to hook up your HTML element to the required component via JSON
serialization.
Specifying the options
The component has a number of options that can be set using the corresponding properties.
Setting the response time
There is a default 500ms delay before a suggestion is requested. This can be specified by setting the delay property to an integer value. The following will set a delay of 300ms:
"delay": "300"
Number of characters before searching
By default a suggestion is not requested until two characters are entered by the user. This can be set using the minLength property. The following example sets it to 4 characters:
"minLength": "4"
Search term delimiter
Individual search terms are separated by the comma character ,. When the user types a comma, the autocomplete will reset and will start matching the next term. The delimiter can be specified using the separator
property. The following sample sets it to a space instead:
"separator": " "
Hooking up to a data source
To auto-suggest values a data source is needed. To supply a data source you must point to a Delegate object using the delegate property in your JSON serialization:
"delegate": {"@": "owner"}
The Delegate
object is a Montage object that implements a method that returns the auto-complete suggestion(s). The method name is ShouldGetSuggestions
, prefixed by the identifier
of the Autocomplete component (which defaults to the label of the JSON object if it is not defined).
This is probably easier understood with an example. Suppose we have an autocomplete component with the label of foo
, as defined below:
"foo": {
"prototype": "montage/ui/autocomplete/autocomplete.reel",
"properties": {
"element": {"#": "component"},
"delay": "300",
"delegate": {"@": "owner"}
},
"bindings": {
"value": {"<->": "@montageComponents"}
}
},
"owner": {
"prototype": "montage-components",
"properties": {
"element": {"#": "autocomplete-example"}
}
The method name used for returning the autocomplete data would be called fooShouldGetSuggestions
. In the above example we would define this method in the montage-components.js file (pointed to by the prototype of the owner object, which is hooked up to foo’s delegate
property).
If the foo object had a identifier
property with a value of bar, the method name would become barShouldGetSuggestions
.
Implementing the *ShouldGetSuggestions
method
This method requires two parameters. The autocomplete
parameter is the autocomplete component instance that is requesting the suggestion data. The second parameter, searchTerm
is the term that the user has entered into the autocomplete input.
It is up to you as the developer as to how you get the suggestions. This could be from an XHR or JSONP call, a predefined list in memory, or so on. What matters is that once you get the results that match the search term, you need to set the suggestions
property of the autocomplete instance to point it to the return results. These results will then be displayed as a drop down list for the user to select the desired result.
The following is an example with the logic for getting the results omitted:
fooShouldGetSuggestions: {
value: function(autocomplete, searchTerm) {
// do some processing such as fetching data via XHR
autocomplete.suggestions = result;
}
}
A quick Autocomplete
example
I’ve created a quick example based off the one in the Kitchen Sink. You can start typing the name of a Montage component, and it will return any component names that match after you have typed two or more characters.
The serialization code is the same as in the above example, except the label is montageComponents
rather than foo
. The HTML that is required is just a simple form with a label and a text input field:
<form>
<label for="component">Montage component:</label>
<input id="montageComponents" data-montage-id="montageComponents" type="text" placeholder="Component name" />
</form>
All the JavasScript that is required can be found in the montage-components.js file, pointed to by the owner
object.
Behind the scenes the components are stored in an array with a key of name
. The montageComponentsShouldGetSuggestions
method checks to see if there are any cached results matching the search term. If so the cached result is returned, otherwise it filters the array to find and return the result, and caches the result so that the search doesn’t have to be performed again for the same search term. Finally, the suggestions
property of the passed autocomplete object is set to the result so that it can be displayed to the user.
You can also check out the KitchenSink for additional examples, such as fetching data from an external source via XHR.