autocomplete.js | Remote AutoComplete Lite, Fast and Stable | v1.7

autocomplete.js

JavaScript project with purpose to propose an fast and lite autocomplete. And there is without dependency.


Lite

Very lite.
< 4KB

So Fast

Only Native JavaScript Function
Great !

Remote Power

No data pre-loaded.
Only easy AJAX.


Download the last stable version


//Simple declaration with default parameters
AutoComplete();

//Call with custom parameters
AutoComplete({
paramName: "query",
method:    "POST",
noResult:  "No item like this",
});
<!--HTML declaration -->
<input type="text"
data-autocomplete="http://…"
data-autocomplete-method="POST"
data-autocomplete-type="HTML"
data-autocomplete-param-name="query2"
data-autocomplete-no-result="Regex no matched"
data-autocomplete-limit="10" />

<!-- data-autocomplete (url)         is required
data-autocomplete-method (GET|POST|PUT|DELETE or all others method) is optional
data-autocomplete-type (JSON|HTML)  is optional
data-autocomplete-param-name        is optional
data-autocomplete-no-result         is optional
data-autocomplete-limit             is optional
-->

It's the main argument. Without it, no autocomplete possible. This argument is string type and is indicate only in HTML. Unlike other autocomplete, autocomplete.js doesn't take argument in JavaScript. This information is exclusively in the input attribute "data-autocomplete". It's for this reason that the selector default value is input[data-autocomplete].

<!-- HTML declaration -->
<input type="text" data-autocomplete="http://…">

limit is a argument added to 1.4 version. It give the possibility to add two conditions easily. The default value is 0.
This is the two features.

  • Limit the number of entity to display. Show only the firsts entities. If this value is equal at 0 (default value), all entities will display.
  • Inverse results. If the value is positive, results will set in the same order. Whereas if the value is negative, all entities are inversed.
    CAUTON: inversed doesn't sort !
This value can be set to two places. Into the JavaScript declaration like the code's example. But you can too set with the DOM. This HTML attribute is « data-autocomplete-limit » and the value is only sent for the current input.

//Show all results
AutoComplete({limit: 0});

//Show the 5 firsts results
AutoComplete({limit: 5}); 

//Show the 10 lasts results
AutoComplete({limit: -10});
<!-- HTML declaration -->
<input type="text"
data-autocomplete="http://…"
data-autocomplete-limit="5" />

selector is array type. This option is a primary information because these are the data which identify inputs to select.

The default array is :

//Default selector
{
selector: [
"input[data-autocomplete]"
//input[data-autocomplete] must  to select all inputs with one URL.
]
} 

//If you use many ID selector
{
selector: [
"#myFirstIDSelector",
"#mySecondIDSelector",     
...
]
}
The rules to select an input text type are the same that CSS (#id, .class, tag, [attr], …). You can read the MDN Documentation for most information.

method is string type. This option is available since the v1.0. The default value is GET.
This option define the method to send the XMLHttpRequest. All methods are defined in the RFC2616 which explain the HTTP1.1 protocol.
This option is a string and the parameter isn't sensible case.

There are two possibilities to set a custom value.

  • In JavaScript with the key limit ;
  • Into the HTML with the DOM attribute data-autocomplete-method.

Caution

Before 1.6 version (1.0 to 1.5), this parameter took only two values (GET and POST). Since, , the method use it depends developper fully. No check applies, only XMLHttpRequest must throw an exception.

//Send GET request with default value
AutoComplete();

//Send GET request in define value
AutoComplete({method: "GET"});

//Send a POST request
AutoComplete({method: "POST"}); 

//Send a PUT request
AutoComplete({method: "PUT"}); 

//Send a DELETE request
AutoComplete({method: "DELETE"}); 
<!-- HTML declaration for a POST request -->
<input type="text"
data-autocomplete="http://…"
data-autocomplete-method="POST" />

headers is object type only declarable in javascript. This option is available since the v1.7. The default value is {"Content-Type": "application/x-www-form-urlencoded"}.

//Send request with specific headers
AutoComplete({
headers: {
'apikey': "myApiKey",
"secretKey": "mySecretKey" 
}
}); 

paramName is string type. This option is available since the v1.0. The default value is q.
It allows define the parameter name which contains the value when the request is send.
This option is settable with two attributes, DOM and/or JavaScript.

  • JavaScript with the attribute paramName ;
  • HTML with the keyword data-autocomplete-param-name

//How custom the parameter name to send request
AutoComplete({paramName: "query_to_search"});
<!-- HTML declaration -->
<input type="text"
data-autocomplete="http://…"
data-autocomplete-param-name="query_to_search" />

noResult is string type. This option is available since the v1.2. The default value is No result.
This option allows given a custom message when there isn't results after one search. The message is usable into the post. CAUTION: If you override the post method, think at given this value when the response is empty.

This option is settable with two attributes, DOM and/or JavaScript.

  • JavaScript with the attribute noResult ;
  • DOM with the attribute data-autocomplete-no-result

//How set the message for a empty response
AutoComplete({noResult: "There isn't results for this search"}); 
<!-- HTML declaration -->
<input type="text"
data-autocomplete="http://…"
data-autocomplete-no-result="Nope Nope Nope… Bad entry" />

open is function type. Its purpose is to bind the LI items responses generate by the post method.

To override the method open, you must respect the prototype.

//Prototype: open method
void function(input, result);
  • First parameter is the HTML input object
  • Second parameter is the HTML div object who are display the results.
  • open doesn't return

The default method is detail here.

//Default open function
{
open: function(input, result) {
//lambda is an anonymous function which take one argument. This argument is an HTML li object
var lambda = function(li) {
    //We add a event tracker. When we click on this HTML li object
    li.addEventListener("click", function(e) {
        var li = e.currentTarget,
        dataAutocompleteValueLabel = "data-autocomplete-value";

        //We push the li value into the input, except if li own a alternative value.
        input.value = li.hasAttribute(dataAutocompleteValueLabel) ? attr(li, dataAutocompleteValueLabel) : li.innerHTML;

        //I push the input value in a input's attribute for stop the results show, while the input value doesn't change.
        attr(input, {"data-autocomplete-old-value": input.value});
    });
};

//We search all li items
var liS = result.getElementsByTagName("li");

//We bind all items
for (var i = liS.length - 1; i >= 0; i--) {
    lambda(liS[i]);
}
}
}

post is function type. Its purpose is the method which insert results in the DOM. It creates the result menu. You can override this method in respect the prototype.

//Prototype: post method
boolean function(result, response, custParams);
  • First parameter is the DOM item result to insert the results
  • Second parameter is the data response
  • Third parameter is the data structure which manage the input
  • post returns boolean type. The return is equal at true if there isn't results. false if there is results.

The default method is detail here.
{
//Default post function
post: function(result, response, custParams) {
//If an exception is throws, the result isn't JSON data.
try {
    //Try parse like JSON data
    response = JSON.parse(response);
    var empty,
        length = response.length,
        li = domCreate("li"),
        ul = domCreate("ul");
       
    //If the response is a JSON array
    if (Array.isArray(response)) {
        //If there is results
        if (length) {
            //We reverse results if parameter is custom
            if (custParams.limit < 0) {
                response.reverse();
            }

            //While there is results, we show in inserting in DOM ul element
            for (var i = 0; i < length && (i < Math.abs(custParams.limit) || !custParams.limit); i++) {
                li.innerHTML = response[i];
                ul.appendChild(li);
                li = domCreate("li");
            }
        //If there isn't results, we give the parameters « noResult »
        } else {
            //If the response is an object or an array and that the response is empty, so this script is here, for the message no response.
            empty = true;
            //The class « locked » on a li element stop the click event
            attr(li, {"class": "locked"});
            li.innerHTML = custParams.noResult;
            ul.appendChild(li);
        }
    }
    //If the result is JSON Object
    else {
        var properties = Object.getOwnPropertyNames(response);

        //Reverse result if limit parameter is custom
        if (custParams.limit < 0) {
            properties.reverse();
        }

        for (var propertie in properties) {
            if (parseInt(propertie) < Math.abs(custParams.limit) || !custParams.limit) {
                li.innerHTML = response[properties[propertie]];
                attr(li, {"data-autocomplete-value": properties[propertie]});
                ul.appendChild(li);
                li = domCreate("li");
            }
        }
    }

    if (result.hasChildNodes()) {
        result.childNodes[0].remove();
    }
    
    result.appendChild(ul);

    return empty;
} catch (e) {
    result.innerHTML = response;
}
}
}

pre is a function with purpose to modify id necessary the value before it send.
The default function is it :

{
pre: function(input) {
return input.value;
}
}

//Prototype
string function(input);
  • pre function take one argument which is the input.
  • pre function return the value for the request. If you want cancel the request in custom case, it's easy. You return an empty string and the request doesn't send it.
    {
    pre: function(input) {
    //If the string length is < 2 chars
    if (input.value.length < 2) {
        //We cancel the request
        return "";
    }
    return input.value;
    }
    }

The method select give possibility to custom the value to insert in your autocomplete input. Default, The method insert the li's value selected, and insert the same value in the input attribute data-autocomplete-old-value. This attribute allows to stop search when a value has been selected (without that it changes).

Default value

select: function(input, item) {
input.value = attr(item, "data-autocomplete-value", item.innerHTML);
attr(input, {"data-autocomplete-old-value": input.value});
}
If you want override this method, this is the parameters descriptions :
  1. input is the autocomplete input
  2. item is the li selected.
The two fields are DOM element.

This feature isn't a argument to initialize your autocomplete but an event to send to reposition the results. This feature can be util if your DOM before your autocomplete input change. With this event, you can easily reposition the div.

var event = new Event('position');
document.querySelector("[data-autocomplete]").dispatchEvent(event);

Caution !

This feature has been added into 1.4 release. The event had like name autocomplete:position and not position. Since 1.5, you can use position.

With it, you can unbind and destroy all events applies on specific input. DOM element to puth results is deleted. All events are deleted.

var event = new Event('destroy');
document.querySelector("[data-autocomplete]").dispatchEvent(event);


Easy custom

You can easily implement a CSS for autocomplete.js. A snippet is available here on CodePen.

So sure

The version 1.7 has been validate by JSHint.
This is quality assurance.

Logs

News

  • HTTP Headers can be customize

How upgrade ?

Download, move, and take a beer (or a tea ?)

Created, developed, designed proposed by