Spring MVC + jQuery Autocomplete example

jquery autocomplete

In this tutorial, we show you how to integrate jQuery autocomplete plugin with Spring MVC.

Tools and Libraries used :

  1. Spring MVC 3.2
  2. jQuery autocomplete plugin – github
  3. Maven 3
  4. Eclipse IDE

Review the tutorial’s flows :

  1. An HTML page, with a textbox.
  2. If the user is tying on the textbox, it will fire an Ajax request (via autocomplete plugin) to Spring controller.
  3. Spring process the user input and return the search result (in JSON format).
  4. The “autocomplete plugin” process the returned result and display the autocomplete suggestion box. See figure above.

1. Project Directory

Review the final project directory structure, a standard Maven project.

spring-mvc-jquery-autocomplete-directory

2. Project Dependencies

Declares Spring, JSTL and Jackson(JSON result).

pom.xml

       <properties>
		<spring.version>3.2.2.RELEASE</spring.version>
		<jstl.version>1.2</jstl.version>
		<jackson.version>1.9.10</jackson.version>
	</properties>

	<dependencies>
		<!-- jstl -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>

		<!-- Spring Core -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- need this for @Configuration -->
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2.2</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- Jackson -->
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-asl</artifactId>
			<version>${jackson.version}</version>
		</dependency>

	</dependencies>

3. Spring MVC – Data Provider

A Spring controller, if user issue a “/getTags” request, Spring will filter out the result with user input and return it in JSON format.

MainController.java

package com.mkyong.web.controller;

import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.mkyong.web.domain.Tag;

@Controller
public class MainController {

	List<Tag> data = new ArrayList<Tag>();

	MainController() {
		// init data for testing
		data.add(new Tag(1, "ruby"));
		data.add(new Tag(2, "rails"));
		data.add(new Tag(3, "c / c++"));
		data.add(new Tag(4, ".net"));
		data.add(new Tag(5, "python"));
		data.add(new Tag(6, "java"));
		data.add(new Tag(7, "javascript"));
		data.add(new Tag(8, "jscript"));

	}

	@RequestMapping(value = "/", method = RequestMethod.GET)
	public ModelAndView getPages() {

		ModelAndView model = new ModelAndView("example");
		return model;

	}

	@RequestMapping(value = "/getTags", method = RequestMethod.GET)
	public @ResponseBody
	List<Tag> getTags(@RequestParam String tagName) {

		return simulateSearchResult(tagName);

	}

	private List<Tag> simulateSearchResult(String tagName) {

		List<Tag> result = new ArrayList<Tag>();

		// iterate a list and filter by tagName
		for (Tag tag : data) {
			if (tag.getTagName().contains(tagName)) {
				result.add(tag);
			}
		}

		return result;
	}

}

Tag.java

package com.mkyong.web.domain;

public class Tag {

	public int id;
	public String tagName;

	//getter and setter methods

	public Tag(int id, String tagName) {
		this.id = id;
		this.tagName = tagName;
	}

}
mvc-dispatcher-servlet.xml – Map the resources folder.

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/mvc 
		http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:component-scan base-package="com.mkyong" />

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/pages/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>

	<mvc:resources mapping="/resources/**" location="/resources/" />

	<mvc:annotation-driven />

</beans>

4. jQuery Automplete Plugin

The JSP page below should be self-explanatory.

WEB-INF/pages/example.jsp

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<script src="<c:url value="/resources/core/jquery.1.10.2.min.js" />"></script>
<script src="<c:url value="/resources/core/jquery.autocomplete.min.js" />"></script>
<link href="<c:url value="/resources/core/main.css" />" rel="stylesheet">
</head>
<body>
  <h2>Spring MVC + jQuery + Autocomplete example</h2>

  <div>
	<input type="text"  id="w-input-search" value="">
	<span>
	  <button id="button-id" type="button">Search</button>
	</span>
  </div>
	
  <script>
  $(document).ready(function() {

	$('#w-input-search').autocomplete({
		serviceUrl: '${pageContext.request.contextPath}/getTags',
		paramName: "tagName",
		delimiter: ",",
	   transformResult: function(response) {
		    	
		return {      	
		  //must convert json to javascript object before process
		  suggestions: $.map($.parseJSON(response), function(item) {
		            	
		      return { value: item.tagName, data: item.id };
		   })
		            
		 };
		        
            }
		    
	 });
				
  });
  </script>
	
</body>
</html>

#1. The autocomplete plugin will generate the suggestions list with following HTML tags.


<div class="autocomplete-suggestions">
    <div class="autocomplete-suggestion autocomplete-selected">...</div>
    <div class="autocomplete-suggestion">...</div>
    <div class="autocomplete-suggestion">...</div>
</div>

So, you need to style it, for example :

main.css

.autocomplete-suggestions { border: 1px solid #999; background: #FFF; overflow: auto; }
.autocomplete-suggestion { padding: 5px 5px; white-space: nowrap; overflow: hidden; font-size:22px}
.autocomplete-selected { background: #F0F0F0; }
.autocomplete-suggestions strong { font-weight: bold; color: #3399FF; }

#2. Fro this “autocomplete plugin”, the response from the server must be a JSON formatted JavaScript object like this :


{
    suggestions: [
        { value: "Java",        data: "1001" },
        { value: "JavaScript",  data: "1002" },
        { value: "Ruby",        data: "1003" }
    ]
}

#3. Review the following Ajax request


  $('#w-input-search').autocomplete({
	serviceUrl: '${pageContext.request.contextPath}/getTags',
	paramName: "tagName", // ?tagName='user input'
	delimiter: ",",
	transformResult: function(response) {
		    	
	   return {
		        	
	      suggestions: $.map($.parseJSON(response), function(item) {     
		 return { value: item.tagName, data: item.id };
	      })
		            
	   };
		        
	}	    
   });
  1. serviceUrl – Server side URL or callback function that returns the JSON data.
  2. paramName – In this case, it will generate getTags?tagName=user input. Default is ?query=user input.
  3. delimiter – For multiple suggestions.
  4. $.parseJSON (response) – Java will return JSON formatted data, so, you need to convert it to a JavaScript object.

5. Demo

Start and access “http://localhost:8080/SpringMvcExample/“.

Type “java

jquery autocomplete

Type “r

jquery autocomplete

Download Source Code

Download – SpringMvc-Autocomplete-Example.zip (48 KB)

References

  1. jQuery autocomplete plugin
  2. Create a Simple Autocomplete With HTML5 & jQuery
  3. 35+ Best Ajax jQuery Autocomplete Tutorial & Plugin with Examples
  4. jQuery $.parseJSON example
  5. jQuery $.map() example
  6. jQuery $.each() example
  7. Wikipedia : JSON

35 comments on “Spring MVC + jQuery Autocomplete example

  1. I got these errors…

    Uncaught TypeError: Cannot read property ‘replace’ of undefined
    at g.formatResult (jquery.autocomplete.min.js:11)
    at Object. (jquery.autocomplete.min.js:20)
    at Function.each (jquery.1.10.2.min.js:4)
    at g.suggest (jquery.autocomplete.min.js:20)
    at g.processResponse (jquery.autocomplete.min.js:21)
    at Object. (jquery.autocomplete.min.js:19)
    at c (jquery.1.10.2.min.js:4)
    at Object.fireWith [as resolveWith] (jquery.1.10.2.min.js:4)
    at k (jquery.1.10.2.min.js:6)
    at XMLHttpRequest.r (jquery.1.10.2.min.js:6)

    Reply
    1. I think because of this statement : “#2. Fro this “autocomplete plugin”, the response from the server must be a JSON formatted JavaScript object like this :”

      Reply
  2. It help me so much and make me many time to refactor with my style because it’s not run when i rework, i have problem. I have fixed it. I have a notice that Be careful about version Java use in project. This project use Java 1.6, if you use java 1.8, it isn’t work.
    Thanks mkyong very much!

    Reply
  3. I try this, but it response me a error 406:
    El recurso identificado por este requerimiento sólo es capaz de generar respuestas con características no aceptables con arreglo a las cabeceras “accept” de requerimiento

    Why?, thanks

    Reply
  4. when i try to running this example i got this error
    java.lang.IllegalArgumentException: No converter found for return value of type: class java.util.ArrayList

    Reply
  5. can you show me one to many mapping with dynamic from in spring mvc hibernate

    Reply
  6. Hi,
    code is perfectly working. but the value selects from auto dropdown is not set to ng-model of angular. ng-model only taking whatever user types but not selected value.
    can you pls help on that yong??

    Reply
  7. If you want case insensitive searches on the Java arrayList, you might want to modify the code to look like this: (tag.getTagName().toLowerCase().contains(tagName.toLowerCase()))

    Reply
  8. MainController() {
    // init data for testing
    data.add(new Tag(1, “ruby”));
    data.add(new Tag(2, “rails”));
    data.add(new Tag(3, “c / c++”));
    data.add(new Tag(4, “.net”));
    data.add(new Tag(5, “python”));
    data.add(new Tag(6, “java”));
    data.add(new Tag(7, “javascript”));
    data.add(new Tag(8, “jscript”));

    }
    This part gives me compile error..

    Reply
  9. hi sir , can you please publish the spring xt ajax framework .
    it will be so helpful to us.

    Thanks in advance;

    Reply
  10. Great example, can run perfectly. But in my project is giving 406 error.

    Reply
  11. Hi All,
    Thanks!! Can you please tell me how to get data: item.id value in hidden, for ex, if i select java from autocomplete then 1001 in hidden field.

    Thanks
    Anil

    Reply
  12. Hi All,

    I want to insert the multiple row data into database dynamically. Please help me on this.
    new row can be create by pressing a tab button & can be delete by select
    a row then by pressing delete button. After that, I want to insert all the row into
    database. Anyone know this scenario ,how to proceed with spring +
    hibernate + ajax

    Reply
  13. vry nice article!

    JQuery Bootstrap Tokenfield is a pretty jQuery plugin that takes advantage of jQuery and Twitter’s Bootstrap to manage

    tags / tokens in an input field.

    Bootstrap Tags Input is a jQuery plugin that allows you to add, remove, and categorize tags with Twitter Bootstrap user

    interface.

    Features:

    1. Keyboard support (arrow keys, Backspace, delete, Ctrl + A, Cmd + A, Ctrl + C, Cmd + C, Ctrl + V and Cmd + V)Copy &

    paste support

    2. Copy & paste support

    3. Validation states

    4. jQuery UI Autocomplete support

    It may help you understand this using sample :

    http://www.mindstick.com/Articles/22623553-1837-49f3-a883-32716a120865/Bootstrap%20Tokenfield%20and%20autocomplete

    http://sliptree.github.io/bootstrap-tokenfield/

    Reply
  14. it works fine .. thank you .. but i got one issue

    1. i have multiple textbox with different ajax request url ;
    2.All of them working working fine . if i use first textbox with ajax request then rest are not wortking .even its not hitting server

    anyone Please answer how to solve this

    Reply
  15. how to add image in this example
    any one please help me.

    Reply
  16. great post!

    how could send an http url ?

    Reply
  17. Uncaught TypeError: Cannot call method ‘replace’ of undefined .

    I am getting the above error in javascript console. How to resolve this error?

    Reply
  18. I am getting ‘http://localhost:8080/resource/personLookup.htm?term=Te 406 (Not Acceptable)’

    Reply
  19. This example is working properly,bt i want call select function after selecting item.

    My code:its not working

    ******************************

    $(‘#item_name’+item_rowno).autocomplete({
    select: function (e, ui) {
    alert(“hi123”);
    $(“#item_name0”).val(ui.item.label);
    return false;
    },

    serviceUrl: ‘${pageContext.request.contextPath}/forms/admin/addgpatty/getItemList’,
    paramName: “tagName”,
    delimiter: “,”,
    transformResult: function(response) {
    return {
    suggestions: $.map($.parseJSON(response), function(item) {
    $(“#item_id”+item_rowno).val(item.its_id)
    return { value: item.its_name, data: item.its_id };

    })
    };
    },
    });

    Reply
  20. i have added this autocomplete in my project as it is but its is not working at service url please give me solution ,there is not going any call to getTags method

    Reply
  21. Hi Mkyong Thank you very much for all these tutorials. I have a suggestion : Why you don’t use gitHub to post your tutorials 🙂

    Reply
    1. thanks, I’m thinking of this also, put all source code in github.

      Reply
  22. typo mistake
    #2. Fro this “autocomplete plugin”,

    Reply
  23. Great post. I applied and successed. But, I’ve a question, how to use data as a variable in javascript? I want to use it as input to search.

    Reply
  24. very nice tutorial. Took less than 5 mins to implements in an existing project.

    Reply
  25. Very nice article. Thank you so much! In your opinion, jQuery (pure implementation) wins primefaces implementation?

    Reply

Leave a Comment

Your email address will not be published. Required fields are marked *