# 자동완성 기능
---
## jQuery UI 설치
아래 사이트에 접속하여 jQueryUI를 다운 받습니다.
+ http://jqueryui.com/download/
다운 받은 파일의 압축을 해제 후 `jquery-ui.min.css` 파일과 `jquery-ui.min.js` 파일을 각각 css 폴더와 js 폴더에 복사해줍니다.
![Imgur](http://i.imgur.com/VHDsXBP.png)
## Tiles 레이아웃에 jQueryUI 연동하기
**tiles/layouts/classic.jsp**
```
<%@ page pageEncoding="utf-8" session="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<c:url var="bootstrap" value="/css/bootstrap.min.css" />
<link href="${ bootstrap }" rel="stylesheet">
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<Script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<Script src="https://cdn.jsdelivr.net/npm/
[email protected]/dist/umd/popper.min.js"></script>
<Script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<!-- font awesome -->
<Script src="https://kit.fontawesome.com/0f513f1fb4.js" crossorigin="anonymous"></script>
<!-- jquery ui -->
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<Script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<tiles:insertAttribute name="header" />
<tiles:insertAttribute name="content" />
<tiles:insertAttribute name="footer" />
</body>
</html>
```
## 라이브러리 추가하기
**pom.xml**
```xml
...
<!-- JSON View -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib-ext-spring</artifactId>
<version>1.0.2</version>
</dependency>
...
```
## JsonView 추가하기
**servlet-context.xml**
```xml
...
<!-- JsonView -->
<beans:bean id="jsonView" class="net.sf.json.spring.web.servlet.view.JsonView">
<beans:property name="contentType" value="application/json;charset=UTF-8"></beans:property>
</beans:bean>
<!-- JsonViewResolver -->
<beans:bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
<beans:property name="order" value="0" />
</beans:bean>
...
```
## 뷰 페이지에 JS 코드 삽입
**views/books/index.jsp**
```
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="s"%>
<%@ page pageEncoding="utf-8" session="false"%>
<div class="jumbotron">
<h1>Books INDEX</h1>
<p>views/books/index.jsp</p>
<s:authorize access="hasRole('ADMIN')">
<a href="<c:url value="/books/new" />" class="btn btn-lg btn-primary">도서등록</a>
</s:authorize>
</div>
<div class="container">
<!-- 검색 -->
<div class="search">
<c:url var="booksSearchPath" value="/books/search" />
<form action="${ booksSearchPath }" method="get">
<div class="row">
<div class="col-10">
<input name="query" type="text" class="form-control input-lg" id="search" placeholder="도서명으로 검색">
</div>
<div class="col-md-2">
<button type="submit" class="form-control input-lg btn btn-primary">
<i class="fas fa-search"></i>
</button>
</div>
</div>
</form>
</div>
<!-- 도서 -->
<div class="row">
<c:forEach var="book" items="${books}" varStatus="status">
<div class="col-md-4">
<div class="card">
<img src="<c:url value="${ book.image }" />" class="card-img-top" />
<div class="card-body">
<h3 class="card-title">${ book.title }</h3>
<p class="card-text">Some quick example text to build on the
card title and make up the bulk of the card's content.</p>
<a href="<c:url value='/books/${ book.id }' />" class="btn btn-primary">상세보기</a>
<s:authorize access="hasRole('ADMIN')">
<a href="<c:url value='/books/edit/${ book.id }' />" class="btn btn-info">수정</a>
<a href="<c:url value='/books/delete/${ book.id }' />" class="btn btn-danger">삭제</a>
</s:authorize>
</div>
</div>
</div>
</c:forEach>
</div>
</div>
<script>
$(function() {
$("#search").autocomplete({
source : function(request, response) {
$.ajax({
type : 'get',
url : "<c:url value='/api/books/search'/>",
data : {
term : request.term
},
success : function(data) {
var bookList = data.bookList;
response($.map(bookList, function(item) {
return item.title;
}));
}
});
}
});
});
</script>
```
## 컨트롤러 만들기
**APIController.java**
```java
@Controller
public class APIController {
...
@Autowired
BookMapper bookMapper;
@RequestMapping(value = "/api/books/search", method = RequestMethod.GET)
public ModelAndView searchBook(String term) {
List<Book> bookList = bookMapper.search(term);
ModelAndView mv = new ModelAndView();
mv.addObject("bookList", bookList);
mv.setViewName("jsonView");
return mv;
}
}
```
BooksController
```
...
@RequestMapping(value ="/books/search", method = RequestMethod.GET)
public String search(@RequestParam String query, Model model) {
List<Book> books = bookMapper.search(query);
System.out.println(query);
model.addAttribute("books", books);
return "books/index";
}
```
## 맵퍼
BookMapper
```
@Select("select * from books where title like '%'||#{term}||'%'")
List<Book> search(String term);
```
## 주의 사항
---
ajax 호출 시 한글 깨짐 문제 해결법 => URIEncording 추가
tomcat > server.xml
```
# 변경 전
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
# 변경 후
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
```