jQuery Autocomplete
last modified July 13, 2020
In jQuery Autocomplete tutorial, we show how to use the jQuery Autocomplete component. The Autocomplete component displays filtered data from a Java servlet. Sources for this tutorial are available in the authors Github repository.
jQuery is a fast, small, and feature-rich JavaScript library. It makes HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. jQuery UI is a set of user interface widgets, effects, interactions, and themes built on top of the jQuery Library.
Autocomplete
is one of the UI widgets of the jQuery UI
library.
It provides suggestions while we type into the field.
JSON (JavaScript Object Notation) is a lightweight data-interchange format.
It is easy for humans to read and write and for machines to parse and generate.
The official Internet media type for JSON is application/json
.
The JSON filename extension is .json
. There are many libraries to work
with JSON data format in Java; one of them is Jackson.
jQuery Autocomplete example
In the following example, we use an Autocomplete
component to select a bug name.
The names of bugs are stored in a CSV file on the server. The selected bug name is sent and
displayed in a JSP page.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zetcode</groupId> <artifactId>AutocompleteEx</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>AutocompleteEx</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>com.opencsv</groupId> <artifactId>opencsv</artifactId> <version>4.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project>
We use these dependencies in our project. The javax.servlet-api
dependency
provides support for Java servlets. The com.fasterxml.jackson.core
and jackson-databind
are Jackson JARs for working with JSON files. The
opencsv
is used for working with CSV files.
<!DOCTYPE html> <html> <head> <title>jQuery UI Autocomplete</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .ui-autocomplete-loading { background: white url("img/anim_16x16.gif") right center no-repeat; } </style> <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script> $(function () { $("#bugs").autocomplete({ source: "Bugs", minLength: 1, }); }); </script> </head> <body> <form action="showBug.jsp"> <div class="ui-widget"> <label for="bugs">Bugs:</label> <input id="bugs" name="bug"> </div> <br> <div> <input class="ui-widget" type="submit" value="Submit"> </div> </form> </body> </html>
In the index.html
file, we use the Autocomplete
component
in a form tag. The action
attribute points to the showBug.jsp
page, which shows the chosen bug name.
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="https://code.jquery.com/jquery-1.12.4.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
We include the JavaScript libraries and CSS styles for the Autocomplete
component.
<script> $(function () { $("#bugs").autocomplete({ source: "Bugs", minLength: 1, }); }); </script>
The Autocomplete
component is created. The source
option points
to the Bugs
Servlet, which returns data in a JSON format. The minLength
option specifies the minimum number of characters a user must type before a search is performed.
<input id="bugs" name="bug">
The Autocomplete
is tied to this input tag.
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Bug</title> </head> <body> <p> Chosen bug: <%= request.getParameter("bug")%> </p> </body> </html>
In the showBug.jsp
JSP file, the selected bug is printed.
Assasin bug, Avondale spider, Backswimmer, Bamboo moth, Banana moth, Bed bug, Black cocroach, Blue moon, Bumble Bee, Carpenter Bee, Cattle tick, Cave Weta, Cicada, Cinnibar, Click beetle, Clothes moth, Codling moth, Centipede, Earwig, Eucalypt longhorn beetle, Field Grasshopper, Garden slug, Garden soldier, German cockroach, German wasp, Giant dragonfly, Giraffe weevil, Grass grub, Grass looper, Green planthopper, Green house spider, Gum emperor, Gum leaf skeletoniser, Hornet, Mealybug, Mites, Mole Cricket, Monarch butterfly, Mosquito, Silverfish, Wasp, Water boatman, Winged weta, Wolf spider, Yellow Jacket, Yellow Admiral
In the WEB-INF/bug.csv
file, we have a list of bug names.
These names are going to be loaded when the web application receives a
GET request from the client.
package com.zetcode.web; import com.zetcode.service.ReadBugs; import com.zetcode.util.Utils; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "Bugs", urlPatterns = {"/Bugs"}) public class Bugs extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); String term = request.getParameter("term"); String q = term.toLowerCase(); List<String> bugsList = ReadBugs.readAll(getServletContext()); List<String> filteredBugsList = Utils.filterListByTerm(bugsList, q); String json = Utils.list2Json(filteredBugsList); response.getWriter().write(json); } }
This is the Java servlet which receives a GET request with a parameter called term
.
The servlet reads the list of bug names, filters it by the retrieved term, and transforms it
into a JSON string.
response.setContentType("application/json");
We set the response type to application/json
.
String term = request.getParameter("term"); String q = term.toLowerCase();
We get the search term and change it to lowercase.
List<String> bugsList = ReadBugs.readAll(getServletContext()); List<String> filteredBugsList = Utils.filterListByTerm(bugsList, q); String json = Utils.list2Json(filteredBugsList);
These three methods read the data, filter it, and transform it into JSON.
response.getWriter().write(json);
The final JSON string is sent to the client.
package com.zetcode.service; import com.opencsv.CSVReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletContext; public class ReadBugs { public static List<String> readAll(ServletContext context) throws IOException { InputStream is = context.getResourceAsStream("/WEB-INF/bugs.csv"); List<String> bugsList = new ArrayList<>(); try (CSVReader reader = new CSVReader(new InputStreamReader(is))) { String[] nextLine; while ((nextLine = reader.readNext()) != null) { for (String e : nextLine) { bugsList.add(e.trim()); } } } return bugsList; } }
The readAll
method reads all bugs from the CSV file. It uses the Opencsv
library to do the job. It returns a list bug names to the caller.
InputStream is = context.getResourceAsStream("/WEB-INF/bugs.csv");
The servlet context is used to determine the path to the CSV file.
package com.zetcode.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; public class Utils { public static List<String> filterListByTerm(List<String> list, String term) { List<String> matching = list.stream() .filter(e -> e.toLowerCase().startsWith(term)) .collect(Collectors.toList()); return matching; } public static String list2Json(List<String> list) { String json = null; try { json = new ObjectMapper().writeValueAsString(list); } catch (JsonProcessingException ex) { Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex); } return json; } }
We have a Utils
class that contains two methods; one filters
the data and the other one transforms a list to JSON.
List<String> matching = list.stream() .filter(e -> e.toLowerCase().startsWith(term)) .collect(Collectors.toList());
Using Java 8 stream API, we filter the data by the search term.
try { json = new ObjectMapper().writeValueAsString(list); } catch (JsonProcessingException ex) { Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex); }
Using Jackson, we transform a Java list into JSON string.
In this tutorial, we have used jQuery Autocomplete in a Java web application. The Autocomplete component was showing suggestions of available bug names. In our project, we have utilized Jackson and Opencsv libraries.