Live suggestions
For a website visitor, one of the most important search features is to offer autocomplete and/or autosearch. Autocomplete means offering instant search term suggestions while someone is typing. Autosearch is similar, but with instant search results instead of search terms.
As stated in the Introduction, Pandosearch does not provide a graphical search user interface for your website visitors. As there are many ways of technically building and maintaining a website, it is simply not possible for us to provide out-of-the-box plugins and/or libraries for all possible situations.
Instead, this guide provides you with general principles and basic code examples for implementing live suggestions using Pandosearch API data.
Before we start, first some general remarks about how this guide is set up:
- Throughout the guide, we use "visitor" to identify someone using your website to search for information. We use "you" to address the reader of this guide, which we assume to be a web developer responsible for adding Pandosearch to a website.
- For readability, we use the term "website" to identify the Pandosearch implementation target. In practice, this can of course also be other software, e.g. a web application or near-native mobile application.
- We use vanilla JavaScript in this guide, loosely defined as "JavaScript that modern web browsers natively understand". This might feel a bit like "scripting like it's 1999", as we are aware that many people use more advanced JavaScript frameworks and pre-processing tools nowadays. However, as we do not control the technology stack used by our clients, we simply cannot assume any of these tools to be available in your technical setup.
- The main point of the guide is to explain the key concepts and interactions needed to make optimum use of Pandosearch API data. The code examples are therefore deliberately kept short. Your specific situation may thus require adjustments based on functional requirements and/or the technology stack you use.
- While we do not provide code examples for specific web frameworks, we do have knowledge about multiple languages and frameworks. We are happy to provide you with technical guidance for your specific situation. Just contact us through one of the support channels available for your plan and we'll get back to you as soon as possible.
- To provide demo data, we have set up Pandosearch to index all of our developer documentation pages on
developer.pandosearch.com
. This domain name is also the collection name used in the API URLs in the examples.
Let's get started!
Why?
Pandosearch is capable of returning instant search query suggestions
and hits
(search results) while a visitor is typing a search query. For a website visitor, this is probably the most important usability feature you can provide using Pandosearch. There are a couple of reasons for this:
- Instant suggestions enable visitors to e.g. just type "pa" and instantly see "pandosearch" as a suggestion, which can then be searched for without having to type in the full word.
- Pandosearch only suggests words which have been indexed, so when used for search they actually return one or more search results. This prevents people from searching for words which your website does not contain.
- Offering suggestions also helps in preventing spelling errors and other typos, as the correct word (or variation) is automatically suggested.
- With instant hits (search results) enabled, visitors can even bypass the whole process of doing a search query and browsing through a search results page. Instead, visitors have a chance at finding the page they need right from the search box. This can greatly improve your search function's effectiveness, both objectively (less time and effort needed to get from question to answer) and in terms of visitor perception ("Wow, this is fast!").
In short: when adding Pandosearch to your website, we strongly suggest (pun intended) to add live suggestions to your search box, as it greatly improves the user experience, and with that the overall value of the search functionality on your website.
Example implementation
As an example, we'll be implementing live suggestions for our developer.pandosearch.com
collection. When following along, just replace this with your own Pandosearch collection name and you'll get suggestions based on your own data.
Let's start with the end result. Just type "p" and "a" in the search box below to see suggestions and hits appear:
So what is happening here? Let's walk through the code step-by-step.
We start with some basic search form HTML:
<form action="">
<fieldset>
<input type="text" name="q" id="suggest" autocomplete="off" placeholder="Type 'p' and 'a'...">
<div>Suggestions:</div>
<ul id="suggestions"></ul>
<div>Hits:</div>
<ul id="hits"></ul>
</fieldset>
</form>
Some points of note about the HTML:
- The
form
element normally has anaction
attribute pointing to the URL on which search results are displayed. As this is demo code, we do not have such a page here. In your implementation, you do need to set this attribute, as this enables people to still search even when live suggestions are not available. This can be very important for people using screen readers and it is also a general fallback in case your JavaScript code contains a bug or does not work for other technical reasons. - The
fieldset
,div
andul
elements in the HTML do not have any meaning. They only provide a minimum layout for this demo and can safely be replaced by something more suitable for your situation. - The
id
attributes on theinput
andul
elements are used to attach event handlers and insert HTML elements using JavaScript. In your implementation you can use any kind of element selector you want. - The
autocomplete="off"
attribute on theinput
is needed to prevent browsers from also showing live suggestions based on your browser history. If you do not set this attribute, the browser's suggestions will interfere with the suggestions coming from Pandosearch.
The rest of the code is a <script>
element with the JavaScript needed to listen to keyboard events, fetch API data, and finally convert this data to clickable HTML elements.
The general idea is to show suggestions based on keyboard input from visitors:
(function() {
// Select the search box input element
var input = document.getElementById("suggest");
input.onkeyup = function(event) {
// Handle keyup events (code omitted here)
};
})();
- The top-level
(function() {})();
wrapper is to isolate the JavaScript code from the global window namespace. - After that, we fetch the search input HTML element and add a onkeyup event handler to it. This enables us to perform an action every time someone has pressed a key on the keyboard.
In our case, on every input change, we want to fetch Pandosearch Suggest API data, which we do using the somewhat weirdly named, but widely supported XMLHttpRequest object:
input.onkeyup = function(event) {
// Set up an HTTP request to fetch Pandosearch Suggest API data
var xhr = new XMLHttpRequest();
// Ensure user input is URL-encoded to avoid URL parsing errors
var q = encodeURIComponent(event.target.value);
var uri = `https://public.pandosearch.com/developer.pandosearch.com/suggest?q=${q}`;
// Initialize the request
xhr.open('GET', uri);
xhr.onreadystatechange = function() {
// Handle HTTP request state changes (code omitted here for readability)
};
// Send the request
xhr.send();
}
With the code above, on every character you type, the Pandosearch Suggest API action is called.
For this demo, the following JSON response data is of interest:
suggestions
– A list of search query suggestions based on the input given. For "pa", this will include "pandosearch" and other words starting with "pa".hits
– A list of the most relevant documents Pandosearch has found for the search query "pa". In this demo, this will include developer documentation pages with "pa" in the title and/or body content.
The main thing you need to do is to convert the raw JSON response data to HTML elements to display to your visitors.
Given how XMLHttpRequest
works, we unfortunately first need a bit of boilerplate before we do the actual data handling:
xhr.onreadystatechange = function() {
// Return immediately if the request has not finished yet
if (xhr.readyState !== XMLHttpRequest.DONE) {
return;
}
// `xhr.status` contains the HTTP response code, which is 200 in case of success
if (xhr.status === 200) {
// Do the actual data handling (code omitted here for readability)
}
else {
// For all other response codes, show an error message in the JavaScript browser developer console
console.error('Request failed. Returned status of ' + xhr.status);
}
};
With this out of the way, let's continue to the actual data processing. This is a bit more code, as vanilla JavaScript can be somewhat verbose when manually creating and inserting DOM elements.
The code is split into separate sections for suggestions
and hits
handling:
if (xhr.status === 200) {
// Convert raw JSON data to JavaScript data to work with
var json = JSON.parse(xhr.responseText);
// SUGGESTIONS HANDLING
// Select DOM element to add suggestions to
var suggestions = document.getElementById("suggestions");
// Remove any existing content from previous calls
suggestions.innerHTML = "";
// For each suggestion, create a list item containing a link to the search results page
json.suggestions.forEach(function(suggestion) {
var li = document.createElement("li");
var a = document.createElement("a");
a.setAttribute("href", `./search.html?q=${encodeURIComponent(suggestion.text)}`);
// We use `textContent` here to make sure data is inserted as plain text.
// Depending on your configuration, an HTML version with highlighing may also be available.
a.textContent = suggestion.text;
li.appendChild(a);
suggestions.appendChild(li);
});
// HITS HANDLING
// Select DOM element to add hits to
var hits = document.getElementById("hits");
// Remove any existing content from previous calls
hits.innerHTML = "";
// Return here if hits is not iterable (which can be the case depending on implementation)
if (!Array.isArray(json.hits)) {
return;
}
// For each hit, create a list item containing a link to the document.
// The document title is used as link text.
json.hits.forEach(function(hit) {
var li = document.createElement("li");
var a = document.createElement("a");
a.setAttribute("href", hit.url);
// We use `innerHTML` as Pandosearch highlights the part of the title matching the search query.
// The markup used for highlighting is configurable for every implementation.
a.innerHTML = hit.title;
li.appendChild(a);
hits.appendChild(li);
});
}
The code comments should explain every step along the way. Some general remarks:
- We use the Array.prototype.forEach() method to loop through both data arrays. This is a standard feature nowadays, but not supported in older versions of Internet Explorer (IE). This can be replaced with for statements if needed.
- For suggestions: the
./search.html
search results page link is for illustration purposes only and should be replaced with the correct search results page path for your website.
And with this done, we have a fully working live suggestions implementation. Just take a look at the source of this page to see all source code in one place. You can freely copy-paste all of it and use it on your website, but it might be a good idea to first read the following section...
Real-world usage
As said in the introduction, this guide aims to provide a starting point, not a full-blown implementation covering all possible features and edge cases.
When implementing live suggestions on your website, here are a couple of things you might want to consider:
- While our
keyup
event handler works, it is not fine-tuned to our needs. The API is called on every keystroke, including Shift, Ctrl, and other non-character keys. Although Pandosearch is built for heavy request loads, firing unnecessary requests may still negatively impact user experience depending on your visitors' network connection quality. - Also not included in the example are key bindings for the up and down arrow keys and Enter key for navigating and selecting suggestions and hits. Adding this greatly improves the user experience for users with a keyboard as their preferred method for navigation.
- We did not touch the subject of accessibility, as it would distract from the main message of this guide. Depending on your domain, you may need to include this when implementing live suggestions. The Accessibility pages on MDN are a great starting point for further research.
- Styling (CSS) is intentionally left up to you, as you know best what fits within the overall design of your website.
Given all the above, you may want to consider an existing autocomplete widget or library, either in vanilla JavaScript or specifically built for the JavaScript framework(s) you already use. This can be a great choice, as things like sophisticated keyboard event handling and accessibility support are often built-in, potentially saving you a ton of work. When investigating this option, do make sure you look for the ability to customize the live suggestions HTML output, specifically in the following ways:
- Ensure that you are able to generate two different lists of HTML elements (suggestions and hits). Some autocomplete widgets assume homogeneous data, which can make it hard or even impossible to show Pandosearch suggestions and hits simultaneously.
- Ensure that you are able to show direct hyperlinks in the live suggestions. Some autocomplete widgets assume that you only want to show suggestions to use as an
input
value. In case of instant hits, this is not enough, as they contain a direct link to a webpage and not a suggestion for a search query.
And that's it for this guide. Up to the next one: search results.