Dependencies
Name | File |
---|---|
Core | dist/js/core.js |
Selectmenu | dist/js/selectmenu.js |
Assets
Type | File |
---|---|
js | dist/js/autocomplete.js |
css | dist/css/autocomplete.css |
less | dist/less/autocomplete.less |
scss | dist/scss/autocomplete.scss |
Examples
One Selection, Predefined Data.
Bare bones Autocomplete example. You can select one result from a prefefined list of data or enter your own text.
Four Selections
Same setup as the last, except this time you can select up to four entries. You can change the number of selections with the limit (or data-limit) config option.
Categories & Headers
To use categories, your data must be an array of objects with a 'label' and 'items' property. The 'items' is an array of results the user can select from and each result must contain at least a 'label' and 'value' property.
Remote URLs
Same setup as the last (up to four total entires) but this time we're hitting a remote endpoint for data. You can achieve remote/xhr ability by hooking into the request events (see Events Section).
Comma Seperate
Add the ability to split user entires by comma and enter those values into the selections stack with the comma (or data-comma) config option.
Only Allow Result Selections
Retstrict users to only select results from the result list and NOT enter anything they choose with the anything (or data-anything) config attribute.
Removed Tag UI
Remote the tag interface easily. Just set the notags (or data-notags) config option to true.
Setup
<div class="mk-ac-root">
<input class="mk-ac" type="text" name="search" aria-label="Search for Stuff" placeholder="Search..." />
</div>
Configuration Options via Data-Attributes
There are two ways to configure Autocomplete, the first of which is by providing data attributes on the root input. Below is a list of all possible data attributes you may add to configure an instance. All data attributes are optional.
<div class="mk-ac-root">
<input type="text"
name="search"
aria-label="Search for Stuff"
<!-- Number of characters before filtering/requesting data. Default is 1. -->
data-chars="3"
<!-- Keeps the list of results open (after selecting) when set to true. Default is false. -->
data-persistopen="true"
<!-- time in milliseconds for a data request to kick off after user entry. Default is 300. -->
data-time="500"
<!-- total number of possible results a user can select. Default is 1. -->
data-limit="4"
<!-- Allow the user to enter, or 'select,' anything they like, including their own input. Default is true. -->
data-anything="true"
<!-- Allows commas to seperate user entered values and add them to the selection list. Default is false. -->
data-comma="true"
<!-- Allows searching any data fields, or omission of a default. Default is "value,label". -->
data-searchkeys="label,myOtherField"
<!-- Remove the tag UI. Default is false. -->
data-notags="false"
<!-- Allows delete (when text entry is '') to pop the last selected items from selections. -->
<!-- Default is false for single select and true for more than one (limit > 1). -->
data-doubledelete="true"
placeholder="Search..." />
</div>
Instantiation
Below is an example of instantiating an Autocomplete. Like all other Mk components, the first argument is the root and the second is configuration options. In the example below, we've provided all possible config options, however, all config properties are completely optional.
//get autocomplete object
var Autocomplete = Mk.get('Autocomplete');
//
//create instance
var autocomplete = new Autocomplete('#selector', {
//number of selections user is allowed. Default is 1
limit: 1,
//number of characters typed by user before kicking off a request/search. Default is 1
chars: 3,
//keeps the list of results open (after selecting) when set to true. Default is false.
persistopen: true,
//delay before trigering request events for data. Default is 300.
time: 500,
//allow the user to input/select anything (including anything they enter manually) Default is true.
anything: true,
//allows the doubledelete functionality to pop old selections. Default is true.
doubledelete: false,
//hide the tag UI. Default is false.
notags: false,
//allow comma seperated user input to be split and added to selections. Default is false.
comma: true,
//allows searching any data fields, or omission of a default. Default is "value,label".
searchkeys: "label,myOtherField",
//data you would like to provide on instantiation (vs. remote requests).
//you can also do both static and remote data.
data: [
..predefined data set..
{
label: 'Example Result 1',
value: 'my-result-key'
}
],
//template overrides/additions
templates: {
..template overrides..
},
//format overrides/additions
formats: {
..format overrides..
},
//events you want bound
events: {
..you can bind events here or by using on() one() and off()..
}
});
Dynamic Data and Remote Urls
Autocomplete does not take care of XMLHttpRequests, JSONP, or any other method of retrieving dynamic data to populate a users search. We do, however, provide the proper hooks for you to tie your own custom requests into the Autocomplete. This is actually great news. Now you can use whatever existing tools for remote requests your project is already using. Below is an example of a JSONP call using jQuery, which hooks into the Autocomplete system.
//get the autocomplete object
var Autocomplete = Mk.get('Autocomplete');
//
//create an instance
var autocomplete = new Autocomplete('.mk-ac-root' /*, options */);
//will keep refernece to our ajax request
var xhr;
//
// set the request.send and request.abort events
autocomplete.on('request.send', function (query, requestnum) {
//notify screen readers and add optional loading indicator
ac.notify(ac.NOTIFY_STATES.LOADING, query);
//
//you can use the 'requestnum'
//to catch situations where an abort() procedure isn't possible.
//see the success method for more info
xhr = $.ajax({
url: 'http://dev.markitondemand.com/Api/v2/Lookup/jsonp',
data: {input: query},
type: 'get',
dataType: 'jsonp',
success: function (data) {
//
//requests is a number keeping track of the current request count.
//you can use that to check if a request is 'stale' and leave or abort an old request.
if (autocomplete.requests > requestnum) {
//exit, we have a more current request coming
return;
}
//
//autocomplete expects two properties to function correctly: value and label.
//our API endpoint does not hand back objects with those properties, but we can set them...
autocomplete.each(data, function (obj, index) {
obj.label = obj.Name;
obj.value = obj.Symbol;
});
//
//We're also going to store the retrieved data in the autocomplete cache.
//This way if the user searches the same term again, we'll pull it from cache vs. sending another request.
autocomplete.setCache(query, data);
//
//finally, it's time to render out data.
autocomplete.render(data, query);
},
error: function () {
//autocomplete has events already set up if/when an error occurs.
//The events notify screen readers and users of what's going on, so it's important to wire them in.
//you can also add your own handlers to the request.error event.
autocomplete.emit('request.error');
}
});
//
// lets also set up an abort events
autocomplete.on('request.abort', function () {
//abort our xhr request if possible.
//we can also use the requests/requestnum logic to do our own aborting.
if (xhr) xhr.abort();
})
});
Events
All events are part of the Mk EventEmitter and *not* added to the DOM. Events are also called in context of the component instance so it isn't a great idea to use a proxy function to change context, as you'll loose a lot of beneficial object access.
render
Fired when data has been retrieved and the list is ready to be built. Binding this event replaces the original rending with your own, custom, rendering.
instance.on('render', function (data) {
console.info(data);
});
change
Fires when autocomplete value changes.
instance.on('change', function () {
console.info('base 64:', this.value);
console.info('raw objects:', this.selections);
});
submit
Fires when autocomplete submit button is clicked/pressed.
instance.on('submit', function () {
console.info('base 64:', this.value);
console.info('raw objects:', this.selections);
});
show
Fired when menu is shown.
instance.on('show', function () {
console.info('Menu has opened!');
});
hide
Fired when menu is hidden.
instance.on('hide', function () {
console.info('Menu has closed!');
});
activate
Fired when an option becomes active.
instance.on('activate', function (option, keyboard) {
console.info('active option:', option);
console.info('came from keyboard (vs mouse):', keyboard);
});
disabled
Fired when selectmenu is disabled, if previously enabled.
instance.on('disabled', function () {
console.info('Selectmenu has been diabled.');
});
enabled
Fired when selectmenu is enabled, if previously disabled.
instance.on('enabled', function () {
console.info('Selectmenu has become enabled.');
});
update
Fired when updates are made to the rendered UI through the use of update().
instance.on('update', function () {
console.info('Changes to the native autocomplete have been applied to the UI.');
});
capacity
Fired when you've reached the selection limit. Does not fire for single selects.
instance.on('capacity', function () {
console.info('We reached capacity!');
});
create.tag
Fired when a tab is being created. You can customize the tag properties through here.
instance.on('create.tag', function (o) {
o.label = 'New Label!';
});
request.send
Used when hooking into request logic to send requests to the server for data.
instance.on('request.send', function (query, requestnumber) {
console.info('about to search for ', query);
});
request.error
Since remote requests are left the end developers, this event must be emit by the end developer as well, typically in an error handler. Since the end developer emits this event, you may pass in any arguments you like.
instance.on('request.error', function () {
console.info('request failed');
});
request.abort
Fired when a request is being aborted.
instance.on('request.abort', function () {
console.info('my request is being aborted due to new user actions.');
});
API
Below are the different public properties and methods accessible to you, the end developer. All of these are accessible on your Autocomplete [ac] instance as well as inside event handlers bound to your instance. Some methods have intentionally been left out due to their difficulty tof use for end developers vs. internal use.
Methods
instance.unmount()
Remove all mounted nodes, data, events, and cache associated with the Autocomplete instance to free up memory and resources.
- No params required.
instance.move([up])
Move the active list item up or down from the currently activated.
Parameters
- Name
- up
- Type
- Boolean
- Description
- Set to true to move up the list. Default is false.
instance.search(key[, add])
Runs a search for the query.
Parameters
- Name
- key
- Type
- String
- Description
- a string representing query text.
- Name
- add
- Type
- Boolean
- Description
- Add the the current query, or replace the current query. Default is false (replace).
instance.request()
Invokes the request event handlers associated with the autocomplete instance. If your autocomplete uses dynaimc data (API endpoints), setup a requset event to hook your requset into.
- No params required.
instance.flatten(value)
Invokes JSON.stringify and btoa on an object.
Parameters
- Name
- value
- Type
- Object
- Description
- Object to convert to a flattened string.
instance.unflatten(value)
Invokes atob and JSON.parse on a string.
Parameters
- Name
- value
- Type
- String
- Description
- String to convert back into an object.
instance.hasCache(key)
Returns true when cache exists for a query, false when it does not.
Parameters
- Name
- key
- Type
- string
- Description
- a previously searched query.
instance.getCache(key)
Returns data for a previously cached query.
Parameters
- Name
- key
- Type
- string
- Description
- a previously searched query.
instance.setCache(key, data)
Caches object for a given query.
Parameters
- Name
- key
- Type
- string
- Description
- a string represending query text.
- Name
- data
- Type
- Object/Array
- Description
- Object to be cached.
instance.data([value])
Generate a JSON representation of the current autocomplete state.
Parameters
- Name
- value
- Type
- String
- Description
- Cache key for query data. Empty will give you static data (if provided).
instance.filterData(key, data)
Filters a dataset by query text.
Parameters
- Name
- key
- Type
- String
- Description
- a string represending query text.
- Name
- data
- Type
- Array
- Description
- A dataset as Array (typically of objects).
instance.prepData(data[, query])
Prep a date set for use with templating and user interactions.
Parameters
- Name
- data
- Type
- Array
- Description
- An array of (typically) objects. Objects must contain a 'value' and 'label' property for templating and mapping.
- Name
- query
- Type
- String
- Description
- A text term used for term highlighting results for the user.
instance.select(value[, silent])
Selects a value from results, or a custom value provided by you.
Parameters
- Name
- value
- Type
- String
- Description
- a flattened string representing a selection object.
- Name
- silent
- Type
- Boolean
- Description
- Pass true to prevent change events from triggering.
instance.deselect(value[, silent])
Deselects a value from results, or a custom value provided by you.
Parameters
- Name
- value
- Type
- String
- Description
- a flattened string representing a selection object.
- Name
- silent
- Type
- Boolean
- Description
- Pass true to prevent change events from triggering.
instance.deselectAll([silent])
Removes all current selections.
Parameters
- Name
- silent
- Type
- Boolean
- Description
- Pass true to prevent change events from triggering.
instance.exists(value)
Check raw object against autocomplete selections for a match.
Parameters
- Name
- value
- Type
- Object
- Description
- Object with a property named 'value' to check for selection matches.
instance.abort()
Invokes the abort event to let end developer know they should cancel their current request, if any.
- No params required.
instance.error()
Method invoked when request error event is emit. When making requests for search term data, if an error occurs, emit the error event to invoke this functionality.
- No params required.
instance.blur()
Invokes XHR abort event and stops internal loading processes.
- No params required.
instance.clear()
Clears screen reader text, list results, and close the menu.
- No params required.
instance.pop()
Pop a selection from the current collection.
- No params required.
instance.notify(type[, query])
Sends text notifications to the screen reader about the state of the Autocomplete. Also applies state classes (request loading for example) to the Autocomplete.
Parameters
- Name
- type
- Type
- CONSTANT
- Description
- CONSTANT value from instance.NOTIFY_STATES which determines what format text to use for screen readers and user message updating.
- Name
- query
- Type
- String
- Description
- Used in the format text for screen readers and user message updates.
- Name
- count
- Type
- Number
- Description
- Result count. Only used for the NOTIFY_STATES.LOADED type representing the number of results returned from the request.
instance.updateRoot()
Updates the root input to reflect the current Autocomplete selections.
- No params required.
instance.render(data[, query])
Renders a result list based off the data parameter provided
Parameters
- Name
- data
- Type
- Array
- Description
- Array of data objects to create a list from. Data objects must contain a 'label' and 'value' property.
- Name
- query
- Type
- String
- Description
- The query term representing the data set. Used for screen readers. If not provided, default is instance.query property.
instance.update()
Make changes to your original input then call this for the UI to consume new changes.
Parameters
- Name
- config
- Type
- Object
- Description
- Configuration object used to rewrite current properties..
Properties
instance.input
The wrapped, rendered triggering input element.
instance.tagroot
The wrapped root element holding tags.
instance.tags
The wrapped collection of UI tags.
instance.live
The wrapped live element responsible for updating screen reader users with atomic information.
instance.notifications
Similar to the live element, but hold notifications such as when a request fails.
instance.isLoading
Boolean representing if the autocomplete is requesting data.
instance.limit
Number of selections an autocompelete instance can have
instance.doubledelete
Boolean representing whether doubledelete is enabled.
instance.multiple
Boolean representing if the use can select more than one result.
instance.capacity
Boolean representing if the autocomplete is at max selections.
instance.anything
Boolean representing if the autocomplete will accept any value or only a value from the result list.
instance.value
String value set on your root's input element. The value is flattened, which means it's an object that's been base64 encoded.
instance.empty
Boolean representing if we have no results.
instance.remote
Boolean representing if our instance is equipt to make XHR requests for data.
instance.searchkeys
Array of object fields to be searched.
instance.deletecount
How many times delete has been pressed in a row. Used with doubledelete.
instance.selections
Array of objects holding the value/label pairs currently selected.
instance.requests
How many requests have been kicked off in total.
instance.cache
Object containing all cached requests.
instance.query
The current query string.