Implementing Twitter Typeahead

Chris Knoll
GRTech Student Blog
5 min readApr 30, 2017

This will be a tutorial demonstrating how to implement an autocomplete / typeahead feature using the Twitter Typeahead autocomplete package.

An example of the working Typeahead functionality. As the user types in the input box, matching results are displayed below that can be selected.

Here are starter files to code along with. The JSFiddle below includes all necessary external resources, but if you were to implement this outside of JSFiddle you would need to install or use a CDN for the following dependencies:

JSFiddle Starter Files

Let’s dive into the code.

We start with a very simple HTML file — all that’s really going on here is that we are making an input with an id of “courses”. This will allow us to identify it both for styling and to apply the typeahead functionality to it.

<div class="container">
<h1>Typeahead Demo</h1>
<div>
<input id="courses" class="typeahead" type="text" placeholder="Classes I've Taken">
</div>
</div>

Next we define an array of strings in our JS file to use as our data source. In this case we have an array called “courses” that contain several different courses offered at Green River.

var courses = ["IT 102 PROGRAMMING FUNDAMENTALS", "IT 114 CompTIA A+ PREP", "IT 131 NETWORKING FUNDAMENTALS", "IT 135 CompTIA SECURITY+ PREP", "IT 141 CS & WORK ENV FOR IT PRO", "IT 160 WINDOWS SERVER ADMIN I", "IT 175 STUDENT ASSISTANT", "IT 178 IT WORK EXPERIENCE", "IT 190 LINUX ADMINISTRATION I", "IT 201 DATABASE FUNDAMENTALS", "IT 206 FRONT-END WEB DEV", "IT 210 INTRO ROUTING/SWITCHING", "IT 219 PROGRAMMING I", "IT 240 WINDOWS SERVER ADMIN II", "IT 243 LINUX ADMINISTRATION II", "IT 340 NETWORK SEC & FIREWALLS", "IT 360 FORENSICS/VULNERABILITY", "IT 460 THREAT ANALYSIS", "IT 426 DESIGN PATTERNS/PRACTICE", "IT 410 DESIGN/SUPPORT NETWORKS", "IT 405 MOBILE DEV FRAMEWORKS", "IT 390 MOBILE DEV/WIRELESS NET", "IT 372 SOFTWARE MAINTENANCE", "IT 355 AGILE DEV METHODS", "IT 344 VIRTUALIZATION & STORAGE", "IT 305 WEB DEV FRAMEWORKS", "IT 301 SYSTEMS PROGRAMMING"];

At the top of our JS file we have a function that is responsible for storing matching entries in our array as the user searches. Whenever the user types in a letter, this code will take the whole input value and search for any matching entries in the courses array. Any it finds will be stored in the matches array.

var substringMatcher = function(strings) {
return function findMatches(q, cb) {
var matches, substringRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substringRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strings, function(i, string) {
if (substringRegex.test(string)) {
matches.push(string);
}
});
cb(matches);
};
};

Next we need to set up Bloodhound — this is the suggestion engine that works in tandem with the autocomplete.

// Register suggestion engine on courses array
var courses = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.whitespace,
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: courses
});

Last we need to hook up the typeahead functionality to our input from the HTML form, and configure what settings we’d like to use:

$('#courses').typeahead({
hint: true,
highlight: true,
minLength: 1
}, {
name: 'courses',
source: courses,
});

These settings make it so that hinting and highlighting are turned on, and minLength: 1 makes it so that there are suggestions being made as soon as the user enters just one character. We give it a name of courses and tell it to use the data source courses, which is our array we defined above. If you want to use more than one data source (multiple arrays) I would suggest merging them and passing in the merged array.

At this point you will have basic autocomplete functionality!

This looks nice — but what happens if someone searches for something that has several results? For example, if a user types in IT, it will match every course in our data array.

With our current implementation, a maximum of 5 results are displayed. We can change this by setting a higher ‘limit’ in our JS file:

...
name: 'courses',
limit: 10,
source: courses,
...
More results!

Now we can see many more results. But our results field is getting a big large. We can reduce the amount of space it takes up on the screen while still being able to show a large amount of results by changing some of the css on the ‘tt-menu’ class, which is what Twitter Typeahead uses to display the results in:

.tt-menu {
max-height: 150px;
overflow-y: auto;
}
The user can now scroll through the results without it taking up too much screen space.

Let’s add a feature to display a friendly message if the user has typed in something that doesn’t match any of our courses. In our JS file let’s add a template for an empty result set:

...
name: 'courses',
limit: 10,
source: courses,
templates: {
empty: [
'<div class="empty-message">No matching courses found!</div>'
]
...

Let’s also add some more css to make sure the message displays nicely:

.empty-message {
padding: 5px 10px;
text-align: center;
}

Now if we run our app and type in something that doesn’t exist in the course list, we’ll get a friendly message:

Here is a JSFiddle of our final code:

--

--