All in one smart search with typeahead standalone

Reading Time < 1 min

Building a smart search that’s fast, autocompletes your queries and displays suggestions is something that everyone would love on their website. Today you will be introduced to a sleek, lightweight and most importantly, a standalone autocomplete library – typeahead-standalone.js.

Why typeahead standalone ?

Typeahead standalone
Before answering that, know that typeahead-standalone is heavily inspired from the famous twitter typeahead library. Although it is a fantastic library (we even recommended it back in the day), it lacks certain features as we will see shortly and it has not been maintained since 2015. Another major drawback is that it depends on jquery. That is not a problem if you are already using jquery, but to include jquery just to be able to use twitter typeahead was a no-go for me!


Coming back to the original question, why typeahead-standalone ? Well, here’s why,

  • it is a feature-rich fast autocomplete library with 0 dependencies
  • its an all-in-one package that comes with an embedded suggestion engine
  • It has in-built support for multiple data sources – Local, Prefetch and Remote
  • it allows you to preload suggestions in advance
  • it caches search queries and its responses
  • it is Framework agnostic! i.e. usable with any framework (React, Vue, Svelte, etc)
  • its UI is 100% customizable
  • it supports all major browsers and is very lightweight (<4kb)
  • it is highly configurable according to your taste and choice

Owing to the above advantages, typeahead standalone makes an excellent choice for an autocomplete library. Lets see how you could make the most of this library.

Setup Typeahead standalone

Start off by installing and then including the library.

# you can install typeahead with npm
$ npm install --save typeahead-standalone
# then include the library & optionally the basic styles
import typeahead from 'typeahead-standalone';
import 'typeahead-standalone/dist/basic.css';

# or in the browser environment
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeahead-standalone/dist/basic.css" />
<script src="https://cdn.jsdelivr.net/npm/typeahead-standalone"></script>

# The library will be available as a global object at "window.typeahead"

In your html, add the required markup

<!-- Html markup -->
<input type="search" id="search" autocomplete="off" placeholder="Search...">

Then, all that remains to do is to initialize typeahead-standalone. Typeahead-standalone accepts an object as an argument. This object contains the configuration options to setup the suggestion engine. There are only 2 mandatory config options required to setup typeahead.

  • input – The input element on your page
  • source – The source of the suggestions (Local, remote or prefetch)

To demonstrate a simple working example, we’ll use an array as the source of suggestions.

typeahead({
    input: document.getElementById("search"),
    source: {
      local: ['Grey', 'Brown', 'Black', 'Blue'],
    }
});

And just by doing that, you’d have a working autocomplete search box. The library provides a lot of different configuration options with sensible defaults, but this is all that is needed to set things in motion. Try entering the letter “B” in the JS Fiddle below and you should see suggestions displayed instantly.


Configure Source

Coming to a more real world usage, we’re definitely gonna interrogate a remote endpoint to retrieve suggestions. Lets see how you could customize the source config option.
Below is a snippet of the source object taken directly from the official documentation.

The source, as you can see can be of 3 types – local, remote or prefetch. It can also be a combination of these types or you can also use all three types of sources together too.

source: {
  local: [],
  remote: {
    url: 'https://remoteapi.com/%QUERY',
    wildcard: '%QUERY',
  },
  prefetch: {
    url: 'https://remoteapi.com/load-data',
  },
  identifier: '',
  transform: function (data) {
    // modify remote data if needed
    return data,
  },
}
  • Local: Used when you want to provide suggestions from a local variable (usually an Array).
  • Prefetch: Used for preloading suggestions from a remote endpoint.
  • Remote: Used when you want to interrogate a remote endpoint to fetch data.
  • Wildcard: While using the remote data source, you must set the url and the wildcard options. Wildcard will be replaced with the search query while executing the request.
  • Transform: You can provide an optional transform() function which gets called immediately after the remote API returns a response. You can modify the response before being processed by typeahead.
  • Identifier: If your remote endpoint returns an array of objects, an identifier is used to identify which property of the object should be used as the suggestion.
    /* Assume the remote endpoint returns */
    [
      { id: 1, color: "Yellow" }, 
      { id: 2, color: "Green" },
      ...
    ]
    

    Now if we wish to use the suggestions as the text defined in the color property, then the identifier must be set to color. (i.e. identifier: "color")


Example using a Remote Endpoint

Here’s a JS fiddle demonstrating how easy it is to get results from a remote endpoint. We will be interrogating the free rest API at https://restcountries.com/v2/name/%QUERY, for example, https://restcountries.com/v2/name/fra gives us a JSON response as follows –

typeahead Remote endpoint response

As you may have observed, the response is an array of objects. Each object has many properties, but the one we are interested in, is the name property which will be displayed as the suggestion. Hence, we set the identifier: "name". Try searching for any country below –

If you keep your network tab in your developer tools open and try typing “FRA”, you will see the necessary requests made to retrieve the suggestions. If you delete “FRA” and search for it again, you will notice that no new requests have been made this time but you have the results in front of you. This is because the results from the previous XHR requests get cached and when the user enters a search query that matches any of the cached results, the cached results are rendered first instead of fetching from the remote API. The effectively limits unnecessary network requests. You could use prefetch to cache results in advance.


Example using Prefetch

Sometimes you may want to load a few suggestions in advance which you know are likely to be searched for. This is where Prefetch comes in. It also allows you to provide an optional when parameter that can control when you want the suggestions to be loaded. Its value defaults to onInit meaning that suggestions will be loaded as soon as typeahead gets initialized. You can set it to onFocus which will cause suggestions to be preloaded as soon as the user focuses the search input.

A JS fiddle to demonstrate prefetch in action is shown below. If you keep your network tab in your developer tools open, you will see an XHR request will be made as soon as you focus the search box. This is because we explicitly set when: 'onFocus'. Try typing the letter “A” to see suggestions of countries beginning with the letter “A” displayed instantly without any XHR request being made.


There are many more configuration options available that will allow you to fine tune typeahead-standalone to your needs. The entire list of possible configuration options are detailed on the official docs.


Styling Typeahead-standalone

By default, typeahead-standlone comes with some basic styling, however, in most of the cases, you’d want to modify its look to be compatible with the general theme of your website. There are 2 ways you could go about this – either override the styles or rewrite the styles altogether (We recommend rewriting them). To override the default styling, you can provide a config option className: 'some-class'. The class that you provide gets applied to the container of the suggestions. Once that’s done, it’s pretty simple to override styles as per your taste. To rewrite styles (recommended), retrieve the latest styles directly and rewrite only the parts that you wish to change.

There are a few classes that can be leveraged to add additional styles too –

  • The input element has a tt-input class
  • The list of suggestions is wrapped in a container with a tt-list class
  • Each suggestion has a class tt-suggestion
  • If the suggestion is selected, then it has a tt-selected class additionally
  • A class tt-hide is added when no suggestions are available

Typeahead provides another config option templates that allows you to customize your UI further and to control various aspects of the suggestion list. Using templates you can display images or colors or any other additional data within your suggestions. There are 5 templates available and their usage is completely optional.

templates: {
  header: () => '<h1>List of Countries</h1>', /* Rendered at the top of the dataset */
  footer: () => '<div>See more</div>', /* Rendered at the bottom of the dataset */
  suggestion: (item) => {   /* Used to render a single suggestion */
    return `<div class="custom-suggestion">${item.label}</div>`;
  },
  group: (groupName) => {   /* Used to render a group */
    return `<div class="custom-group">${groupName}</div>`;
  },
  notFound: () => '<span>Nothing Found</span>', /* Rendered if no suggestions are available */
}

You can provide html snippets for the header, footer, suggestion, group and notFound templates as per your needs. Here’s an example using all available templates to demonstrate how you can style typeahead.

Try searching for the color “Green” and you should see styled suggestions. Next, try searching for “Blue” and see how it is also possible to group suggestions together. To see the notFound template, search for a color like “olive” that’s not available as a suggestion.

Hope this guide helps you get started with typeahead-standalone. Happy fun tweaking 🙂


References

2 comments

  1. how can I search in a nested array like this using this library:

    {
    “resultados”: [
    {
    “id”: 1819,
    “titulo”: “rnCaja de plástico con tapa de pestillos, 61 litros”,
    “slug”: “caja-de-plastico-con-tapa-de-pestillos-61-litros”
    },
    {
    “id”: 1814,
    “titulo”: “rnCaja hermĂ©tica transparente con ruedas y agarradera 113.6 litros”,
    “slug”: “caja-hermetica-transparente-con-ruedas-y-agarradera-1136-litros”
    },
    {
    “id”: 1821,
    “titulo”: ” rnCaja organizadora con tapa 100 Litros “,
    “slug”: “caja-organizadora-con-tapa-100-litros”
    },
    {
    “id”: 5063,
    “titulo”: “Accesorios para Freidora”,
    “slug”: “accesorios-para-freidora”
    },
    {
    “id”: 1834,
    “titulo”: “Anaquel de plástico de 4 repisas rnrn”,
    “slug”: “anaquel-de-plastico-de-4-repisas”
    },
    {
    “id”: 5057,
    “titulo”: “BaterĂ­a de cocina de color plateado”,
    “slug”: “bateria-de-cocina-de-color-plateado”
    },
    {
    “id”: 14002,
    “titulo”: “Bote de basura para oficina”,
    “slug”: “bote-de-basura-para-oficina”
    },
    {
    “id”: 1508,
    “titulo”: “Bote Sterilite para basura tapa con seguro de 28 litros”,
    “slug”: “bote-sterilite-para-basura-tapa-con-seguro-de-28-litros”
    },
    {
    “id”: 1319,
    “titulo”: “BotĂłn de Pánico 268”,
    “slug”: “boton-de-panico-268”
    },
    {
    “id”: 1322,
    “titulo”: “BotĂłn de Pánico PROEMERB”,
    “slug”: “boton-de-panico-proemerb”
    }
    ],
    “numeroResultados”: 10
    }

Leave a Reply