Kamil autocomplete

Dependency-free and highly customisable autocomplete widget

Basic usage

Install the library through NPM:


$ npm install kamil --save

or download the zip file.

In the following examples, assume that the source list is:


var tags = ['ActionScript', 'AppleScript', 'Asp', 'BASIC', 'C', 'C++', 'Clojure', 'COBOL', ... ]

The basic usage of Kamil autocomplete is:

<input id="tags" placeholder="search">

var autoComplete = new Kamil('#tags', {
    source: tags
});

The same result can be achieved by passing a selector instead of an array:


<input id="tags" placeholder="search">
<ul id="list">
    <li>ActionScript</li>
    <li>AppleScript</li>
    <li>Asp</li>
    <li>BASIC</li>
    <li>C</li>
    <li>C++</li>
    ...
</ul>

var autoComplete = new Kamil('#tags', { source: '#list' });

Customisation

Kamil is highly customisable; you can pass and change various options through the Kamil object. The table below lists all the available options:

Option Description Type Default
source The list of suggestions given as an array or a selector Array | String null
appendTo Where to append the menu String - selector Directly after the input element
disabled Whether the autocomplete functionality is disabled Boolean false
autoFocus Should the first element be selected once the menu is open? Boolean false
minChars Minimum number of character to type before a search starts Number 1
noResultsMessage Message to display when there are no matches String null
property The property to choose for the suggestion String null - no nested structure
exclude Class name given to the list items to exclude from being part of the data String 'kamil-autocomplete-category'
filter The filter function to apply to the source list:

filter: function (listItem, input) { ... }

Function Match anywhere, case insensitive
sort Sort function to sort the items after they have been filtered Function Sort by ascending length

Below you can find some examples of customisation.

Auto focus

<input id="tags" placeholder="search">

var autoComplete = new Kamil('#tags', {
    source: tags,
    autoFocus: true
});

Minimum characters

<input id="tags" placeholder="search">

var autoComplete = new Kamil('#tags', {
    source: tags,
    minChars: 2
});

Try typing 'co' or 'ja'

Sort

<input id="tags" placeholder="search">

var autoComplete = new Kamil('#tags', {
    source: tags,
    sort: function (a, b) {
        return a.localeCompare(b);
    }
});

Extension points

When extending the widget, you have the ability to override or add to the behavior of existing methods. Extension points gives you more freedom than options.

renderItem(ul, item)

The renderItem extension point allows you to change the rendering of each list item. The method must create an item, append it to the ul parameter and return it (the item):

<input id="tags" placeholder="search">

// Set up an array of objects
var tags = [
    {
        label: "jQuery",
        desc: "the write less, do more, JavaScript library"
    },
    {
        label: "jQuery UI",
        desc: "the official user interface library for jQuery"
    },
    {
        label: "Sizzle JS",
        desc: "a pure-JavaScript CSS selector engine"
    }
];

var ac = new Kamil('#tags', {
    source: tags
});

ac.renderItem = function (ul, item) {
    // Render item and append to 'ul'
    var li = document.createElement('li');
    li.innerHTML = "<a>" + item.label + "<br><small>" + item.desc + "</small></a>";
    ul.appendChild(li);

    return li; // Return the list item!
};

// More on events later
ac.on('kamilfocus', function (e) {
    e.inputElement.value = e.item.label;
});

ac.on('kamilselect', function (e) {
    e.inputElement.value = e.item.label;
});

renderMenu(ul, items)

This method controls the rendering of the menu. It is passed an empty ul element and a list of items. Creation of the individual <li> elements should be delegated to _renderItemData() like in the following example:

<input id="tags" placeholder="search">

var ac = new Kamil('#tags6', {
    source: tags
});

ac.renderMenu = function (ul, items) {
    var i, l;

    // Render items
    for (i = 0, l = items.length; i < l; i++) {
    this._renderItemData(ul, items[i], i);
    }

    // Striped menu
    var listItems = ul.getElementsByTagName('li');
    for (i = 0, l = listItems.length; i < l; i++) {
        if (i % 2 === 0) {
            listItems[i].classList.add('striped-even');
        }
    }
}

Categories (example from jQuery UI Autocomplete):

<input id="tags" placeholder="search">

var data = [
        { label: "anders", category: "" },
        { label: "andreas", category: "" },
        { label: "antal", category: "" },
        { label: "annhhx10", category: "Products" },
        { label: "annk K12", category: "Products" },
        { label: "annttop C13", category: "Products" },
        { label: "anders andersson", category: "People" },
        { label: "andreas andersson", category: "People" },
        { label: "andreas johnson", category: "People" }
    ],

    ac = new Kamil('#tags7', { source: data });

// Customise menu rendering
ac.renderMenu = function (ul, items) {
    var self = this,
    currentCategory = "";

    // Loop through items
    items.forEach(function (item, index) {
        var li;

        // Create category
        if (item.category !== currentCategory) {
            var catLi = document.createElement('li');
            catLi.className = 'kamil-autocomplete-category';
            catLi.innerHTML = item.category;

            ul.appendChild(catLi);
            currentCategory = item.category;
        }

        // Create item
        li = self._renderItemData(ul, item, index);
        if (item.category) {
            li.setAttribute('aria-label', item.category + ' : ' + item.label);
        }
    });
};

Methods

The following methods allow you to programmatically control the widget.

close()

Closes the autocomplete menu.

destroy()

Removes the menu and the events attached to the input element.

disable()

Disables the autocomplete.

enable()

Enabls the autocomplete.

option()

Returns the options object.

option(name)

Return the value of the given option name.

option(name, value)

Sets the option to the given value.

start([value])

Starts a suggestions' search. If value is not specified then it takes the input's text.

Events

You can add an event listener using the on method:

autoComplete.on('kamilopen', function (e) {
    ...
});

kamilclose

Triggered when the menu is closed (hidden).

kamilfocus

Triggered when focus is moved to an item. The default behaviour is to replace the input's field with the 'property' option (if it's not specified then it will fallback on 'label' then 'value' then the item's text itself).

kamilopen

Fired when the menu is opened or updated.

kamilselect

Triggered when an item is selected from the menu.

Download and contribute

Contributions are very welcome! Suggest a feature? Spot a bug?

Download