How to attach autocomplete to a text box with a Map returned from Spring controller using jQuery

Scenario

A java.util.Map is returned from a Spring controller as a response to an ajax request from the server. This map, for example, contains names of students as values and their roll numbers as value. This is a sample data and it can be anything that has a key-value pair format. It can be names of Employees and their employee ids, it can be names of company offices and their countries, can be names of exams and their codes etc. This map needs to be attached as a source on a text box which should have autocomplete feature such that when someone starts typing, it should show the names of students or whatever.

What is autocomplete

Autocomplete is a feature which is attached to a text box. A source is provided either as a static data structure(array, map, list etc.) or a dynamic source such as a response to an ajax request. When a user starts typing input into a text box with autocomplete feature, the list of values from the source matching this input are shown as suggestion to the user so that he can find the desired value from the list and select it(See figure left). This saves the user from typing long values and also prevents typing errors since the values are selected from the source provided.

Implementation

Suppose there is a Spring controller method which returns a map of Employee ids as key and their names as input. Its code will be as below :

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class EmployeeController {

  @Autowired
  EmployeeService employeeService;
  
  @RequestMapping("/fetchmap")
  public @ResponseBody Map getEmployeeMap() {
       // call service method which returns the required map
       Map employeeMap = employeeService.fetchEmployeeMap();
       returns employeeMap;         
  }

}

The above code shows a method from a Spring controller which returns a java.util.Map. This method calls an employee service which provides it the map. The details of service class are omitted since they are not relevant to the problem statement. Consider the method fetchEmployeeMap as a method which returns a map with some key-value pairs.

Let there be an input box with id “autoInput” which should have autocomplete feature with the map returned from the above method as source. The code

Let the above controller method is called from a jQuery ajax request as :

$.ajax({
        url : ‘fetchmap’,
        success : function(responseMap) {
                                 
                        }
});

Now the value returned in responseMap is a java.util.Map returned from the server with names of employees as value and their ids as keys. For attaching this map to a text box with id autoInput, we need to iterate this map and attach its value one by one. The code would be :

    $.ajax({
        url : ‘fetchmetadata’, // url which this ajax request will hit
        success : function(responseMap){
            if (response != null) {
                // attach autocomplete using jQuery function
                $(“#autoInput”).autocomplete({
                          source : function(req, res) {
                                          // iterate over map and return the value every time
                                          var valueToAttach = $.map(responseMap, function(key, v){
                                                 return valueToAttach;
                                          });
                                          // add value to autocomplete source
                                          res(valueToAttach);
                                    }
                        });
               }
          }
    });

Explanation

An ajax request is sent to the server using $.ajax() function of jQuery. In ajax success option, jQuery’s autocomplete() function is called on the input box(selected by id) which needs to have autocomplete feature. jQuery’s autocomplete function has a source option which can either take a static array with autocomplete contents or a custom callback function. This callback function expects 2 arguments :
1. request : representing the current value in the input box typed by the user.
2. response : provides the list of suggestions to the user based on his initial input. This option accepts 1 argument which is the value to be added to the autocomplete list.

The response(which is a map) is iterated using $.map() function of jQuery in the callback function of source option and in each iteration, the value component is returned. This value is passed to the response object of the callback function of source option which in turn adds it to the autocomplete list as explained above.

Let’s tweak in :

  1. The example returns the map from a Spring controller but it can be utilized anywhere where autocomplete source is loaded from remote location. There can be a php code, a web service, an asp.net controller on the remote side.
  2. source option of autocomplete can also accept a String. If a string is used, it expects that the string is a URL which returns JSON data. This JSON data is then attached to the input box.
  3. The above code can be embedded into a jsp file, an asp file, an HTMl file etc. Thus this code is also independent of any type of view.
  4. The map which is returned from the server can be prepared using the records fetched from a database, a file with key-value pairs or some other source.

Leave a Reply