Sadot Hernández

Spring Boot + jQuery Autocomplete + Bootstrap 5

PublicadoOctober 31, 2021

Spring Boot: ¿Cómo crear un campo de entrada de autocompletado con Ajax Autocomplete for jQuery?

image

1. Información General

En este tutorial rápido, veremos cómo podemos implementar Ajax Autocomplete for jQuery junto con Spring Boot y PostgreSQL

2. Dependencias

Para crear este ejemplo, usaremos las siguientes dependencias.

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.6</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<groupId>com.zademy.springboot</groupId>
	<artifactId>jquery.autocomplete</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>spring-boot-jquery-autocomplete</name>
	<description>Spring Boot  jQuery Autocomplete</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.thymeleaf</groupId>
			<artifactId>thymeleaf</artifactId>
		</dependency>

		<dependency>
			<groupId>org.thymeleaf</groupId>
			<artifactId>thymeleaf-spring5</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		
		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
		</dependency>
		
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

 

3. Estructura del Proyecto

Antes de saltar al proyecto, creemos la estructura de nuestro proyecto como se muestra a continuación:

4. jQuery AutoComplete

Para nuestro ejemplo haremos uso de jQuery Autocomplete del cual podemos disponer desde la siguiente liga: https://github.com/devbridge/jQuery-Autocomplete

5. Bootstrap 5

Para dar un poco de estilo usaremos Bootstrap 5 del cual podemos disponer desde la siguiente liga:

https://getbootstrap.com/docs/5.0/getting-started/introduction/

6. PostgreSQL

Como ejemplo usaremos la siguiente tabla:

7. Clase Controller

Nuestra aplicación constará de una clase controller de nombre “AutocompleteController”, está contendrá dos métodos.

El primero nos servirá para mostrar nuestro formulario mediante la vista de nombre index.html.

El segundo será el encargado de recibir una petición de tipo GET recuperando el dato que se desea buscar, este a su vez nos regresará una respuesta que contendrá los posibles resultados.

/**
 * The Class AutocompleteController.
 */
@Controller
public class AutocompleteController {

	
	/** The auto complete service. */
	@Autowired
	private AutoCompleteService autoCompleteService;
	
	/**
	 * View index.
	 *
	 * @return the string
	 */
	@GetMapping("/")
	public String viewIndex() {

		return "index";
	}
	
	/**
	 * Obtener datos.
	 *
	 * @param query the query
	 * @return the string
	 */
	@GetMapping(value = "/buscar")
	@ResponseBody
	public String obtenerDatos(@RequestParam(name = "query") String query) {

		Gson gson = new Gson();

		if (query.length() > 2) {

			List<AutoComplete> autoComplete = autoCompleteService.obtenerEmpresas(query);

			return ("{\"suggestions\":" + gson.toJson(autoComplete) + "}");

		}

		return ("{\"suggestions\":}");
	}

}

8. Clase Entidad

Nuestra aplicación constará de una sola clase entidad de nombre “Empresa” que persistirá de nuestra tabla.

/**
 * The Class Empresa.
 */
@Entity
@Table(name = "empresa")
public class Empresa implements Serializable {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 269896572355599004L;

	/** id. */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id_empresa")
	private Integer idEmpresa;

	/** nombre. */
	@Column(name = "nombre")
	private String nombre;

	/**
	 * Instantiates a new empresa.
	 */
	public Empresa() {
		super();
	}

	/**
	 * Gets the id empresa.
	 *
	 * @return the idEmpresa
	 */
	public Integer getIdEmpresa() {
		return idEmpresa;
	}

	/**
	 * Sets the id empresa.
	 *
	 * @param idEmpresa the idEmpresa to set
	 */
	public void setIdEmpresa(Integer idEmpresa) {
		this.idEmpresa = idEmpresa;
	}

	/**
	 * Gets the nombre.
	 *
	 * @return the nombre
	 */
	public String getNombre() {
		return nombre;
	}

	/**
	 * Sets the nombre.
	 *
	 * @param nombre the nombre to set
	 */
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	/**
	 * To string.
	 *
	 * @return the string
	 */
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("Empresa [idEmpresa=");
		builder.append(idEmpresa);
		builder.append(", nombre=");
		builder.append(nombre);
		builder.append("]");
		return builder.toString();
	}

9. Clase Modelo

Para poder mapear los datos de la entidad y jQuery Autocomplete pueda interpretarlos se usará una clase modelo de nombre “AutoComplete”.

/**
 * The Class AutoComplete.
 */
public class AutoComplete implements Serializable {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 4349269184028309995L;

	/** data. */
	private Integer data;

	/** value. */
	private String value;

	/**
	 * Gets the data.
	 *
	 * @return the data
	 */
	public Integer getData() {
		return data;
	}

	/**
	 * Sets the data.
	 *
	 * @param data the data to set
	 */
	public void setData(Integer data) {
		this.data = data;
	}

	/**
	 * Gets the value.
	 *
	 * @return the value
	 */
	public String getValue() {
		return value;
	}

	/**
	 * Sets the value.
	 *
	 * @param value the value to set
	 */
	public void setValue(String value) {
		this.value = value;
	}

	/**
	 * To string.
	 *
	 * @return the string
	 */
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("AutoComplete [data=");
		builder.append(data);
		builder.append(", value=");
		builder.append(value);
		builder.append("]");
		return builder.toString();
	}

}

10. Servicio e Implementación

Ahora crearemos una interfaz de nombre “AutoCompleteService” en nuestro paquete servicios, este tendrá un método abstracto los cuales conformaran nuestro servicio.

/**
 * The Interface EmpresaService.
 */
public interface AutoCompleteService {

	/**
	 * Obtener empresa.
	 *
	 * @param dato the dato
	 * @return the list
	 */
	List<AutoComplete> obtenerEmpresas(String dato);
	
}

Una vez creada nuestra interfaz “AutoCompleteService” crearemos una clase de nombre “AutoCompleteServiceImpl” en nuestro paquete “impl” que se encuentra dentro del paquete servicios, este implementará el método abstracto que creamos en la interfaz “AutoCompleteService” y a su vez le inyectaremos nuestro repositorio “EmpresaRepository” que nos ayudará a obtener los resultados desde base de datos.

/**
 * The Class AutoCompleteServiceImpl.
 */
@Service
public class AutoCompleteServiceImpl implements AutoCompleteService {

	/** The empresa repository. */
	@Autowired
	private EmpresaRepository empresaRepository;

	/**
	 * Obtener empresa.
	 *
	 * @param dato the dato
	 * @return the list
	 */
	@Override
	public List<AutoComplete> obtenerEmpresas(String dato) {

		List<Empresa> empresas = empresaRepository.findByNombreLike(dato);

		List<AutoComplete> autoCompletes = new ArrayList<>();

		for (Empresa empresa : empresas) {

			AutoComplete autoComplete = new AutoComplete();
			autoComplete.setData(empresa.getIdEmpresa());
			autoComplete.setValue(empresa.getNombre());
			autoCompletes.add(autoComplete);

		}

		return autoCompletes;
	}

11. API jQuery Autocomplete

Para poder implementar jQuery Autocomplete en nuestro proyecto solo necesitaremos de siguiente script.js:

/* AUTOCOMPLETE EMPRESA O PRODUCTO*/
$("#autocomplete").autocomplete({

	serviceUrl: '/spring-autocomplete/buscar',

	onSelect: function(suggestion) {

	},
	showNoSuggestionNotice: true,
	noSuggestionNotice: 'No se encontro ningún resultado.'
});

Para más referencias sobre la API: https://github.com/devbridge/jQuery-Autocomplete

12. Resultado

Para poder ver nuestro ejemplo solo necesitamos ingresar la siguiente url: http://{host:puerto}/spring-autocomplete

Si gustas ver el código fuente, este está disponible en Gitlab.

Referencias

Tomas Kirda. (24 de Enero de 2021). devbridge. Obtenido de www.devbridge.com: https://github.com/devbridge/jQuery-Autocomplete