본문 바로가기
JavaScript/Ajax

Ajax) 검색어 자동완성 기능 (Autocomplete)

by 박채니 2022. 7. 12.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


검색어 자동완성

 

https://jqueryui.com/autocomplete/

 

Autocomplete | jQuery UI

Autocomplete Enables users to quickly find and select from a pre-populated list of values as they type, leveraging searching and filtering. The Autocomplete widgets provides suggestions while you type into the field. Here the suggestions are tags for progr

jqueryui.com

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/

 

Autocomplete Widget | jQuery UI API Documentation

Description: Autocomplete enables users to quickly find and select from a pre-populated list of values as they type, leveraging searching and filtering. Any field that can receive input can be converted into an Autocomplete, namely, elements, elements, and

api.jqueryui.com

위와 같은 옵션, 메소드, 이벤트 등을 제공해주며, 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