안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
검색어 자동완성
https://jqueryui.com/autocomplete/
jQuery UI를 사용하여 구현해보려고 합니다.
<html>
<head>
<meta charset="UTF-8">
<title>ajax - autoComplete</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
<script src="<%= request.getContextPath()%>/js/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
</head>
<body>
<h1>ajax - autoComplete</h1>
<fieldset>
<legend>검색어 자동완성</legend>
<input id="tags" />
</fieldset>
<script>
$( function() {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$( "#tags" ).autocomplete({
source: availableTags
});
} );
</script>
</body>
</html>
위처럼 #tags에 autocomplete을 적용하였고 source에 검색단어들을 모아둔 배열을 전달해주었습니다.
<h1>ajax - autoComplete</h1>
<fieldset>
<legend>검색어 자동완성</legend>
<input id="classmates" />
</fieldset>
<script>
$("#classmates").autocomplete({
source(request, response) {
console.log(request);
}
});
source를 메소드 형식으로 변경하였으며, request는 key up 이벤트가 있을 때마다 호출이 되는 것을 확인할 수 있습니다.
(request의 term 속성 값)
response는 함수이며, 조회된 값을 response에 전달하고 HTML로 변환하여 보여주는 역할을 합니다.
request의 term 속성 값을 서버로 보내 서버에서 해당하는 단어들을 보여주도록 하겠습니다.
autoComplete.jsp
<h1>ajax - autoComplete</h1>
<fieldset>
<legend>검색어 자동완성</legend>
<input id="classmates" />
</fieldset>
<script>
$("#classmates").autocomplete({
source(request, response) {
console.log(request);
const {term} = request;
if(!/.+/.test(term)) return; // 한글자 이상 입력되지 않았다면 return
$.ajax({
url : '<%= request.getContextPath()%>/classmates',
method : 'GET',
data : {term},
success(csv) {
console.log(csv);
},
error(jqxhr, statusText, err) {
console.log(jqxhr, statusText, err);
}
});
}
});
</script>
ClassmateServlet
@WebServlet("/classmates")
public class ClassmatesServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private List<String> classmates = Arrays.asList("고미송", "김건우", "김선아", "김승원", "김승환", "김재경", "김지윤", "김태연", "남주희", "박민서", "박민지", "박수진", "박우석", "박채은", "박태준", "백도훈", "백승윤", "서은미", "신유경", "오장훈", "이동하", "이윤정", "임규완", "전일찬", "정수아", "정태현", "한해석");
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 사용자 입력 값 처리
String term = request.getParameter("term");
// 2. 업무로직
List<String> resultList = new ArrayList<>();
for(String classmate : classmates) {
if(classmate.contains(term)) {
resultList.add(classmate);
}
}
// 3. 응답처리
response.setContentType("text/csv; charset=utf-8");
PrintWriter out = response.getWriter();
for(int i = 0; i < resultList.size(); i++) {
out.print(resultList.get(i));
// 마지막 요소가 아니라면 , 추가 (csv형태이므로)
if(i != resultList.size()-1) {
out.print(",");
}
}
}
}
넘겨준 term을 받아, 검색어 리스트 (classmates)에 넘어온 term을 포함하고 있다면 resultList에 추가하여 포함된 검색어들을 모아주었습니다.
입력한 값을 포함하고 있는 단어들이 추려진 후 출력되는 것을 확인할 수 있습니다.
이제 이 값들을 response에 전달해주어 검색어 기능을 구현해줘야 합니다.
response에 전달할 때는 [{label:'abc', value;'abc'}, {label:'abc', value:'abc'}....]의 형태로 전달해줘야 합니다.
map을 이용해 처리해보겠습니다.
autoComplete.jsp
<script>
$("#classmates").autocomplete({
source(request, response) {
console.log(request);
const {term} = request;
if(!/.+/.test(term)) return; // 한글자 이상 입력되지 않았다면 return
$.ajax({
url : '<%= request.getContextPath()%>/classmates',
method : 'GET',
data : {term},
success(csv) {
console.log(csv);
const arr = csv.split(",").map((classmate) => ({
label : classmate, // 드러나는 값
value : classmate // 내부적으로 처리되는 값
}));
console.log(arr);
response(arr);
},
error(jqxhr, statusText, err) {
console.log(jqxhr, statusText, err);
}
});
}
});
</script>
원하는 형태로 잘 출력되는 것을 확인할 수 있고, 드랍다운 박스가 잘 나옵니다.
하지만 마우스 커서로 값을 선택하는 건 자연스럽지만, 키보드 방향키로 값을 선택하는 것은 조금 부자연스럽습니다.
https://api.jqueryui.com/autocomplete/
위와 같은 옵션, 메소드, 이벤트 등을 제공해주며, focus이벤트를 이용하여 해당 문제를 해결해보겠습니다.
<script>
$("#classmates").autocomplete({
source(request, response) {
console.log(request);
const {term} = request;
if(!/.+/.test(term)) return; // 한글자 이상 입력되지 않았다면 return
$.ajax({
url : '<%= request.getContextPath()%>/classmates',
method : 'GET',
data : {term},
success(csv) {
console.log(csv);
const arr = csv.split(",").map((classmate) => ({
label : classmate, // 드러나는 값
value : classmate // 내부적으로 처리되는 값
}));
console.log(arr);
response(arr);
},
error(jqxhr, statusText, err) {
console.log(jqxhr, statusText, err);
}
});
},
focus(e, selected) {
return false; // focus가 일어나도 선택되지 않게함
}
});
</script>
키보드로도 잘 작동하는 것을 확인할 수 있습니다.
'JavaScript > Ajax' 카테고리의 다른 글
Ajax) text/html 처리 (0) | 2022.07.12 |
---|---|
Ajax) text/csv 처리 (0) | 2022.07.12 |
Ajax) text/plain 처리 (0) | 2022.07.08 |
Ajax) 동기와 비동기 차이, Javascript로 비동기처리 (0) | 2022.07.08 |
Ajax) 정리 (0) | 2022.07.08 |