위와 같은 자동완성 기능은 우리가 흔히 접할 수 있는 UI 요소입니다.
※ 초성검색 적용 버전 코드도 있습니다.
예제 코드
HTML 태그 사용하기
<input type="text" list="color-list">
<datalist id="color-list">
<option value="빨간색">
<option value="파란색">
<option value="노란색">
<option value="검정색">
</datalist>
HTML에는 Input 자동완성 기능을 이용할 수 있도록 해주는, datalist 태그와 list 속성이 존재합니다.
하지만, 다양한 이벤트 설정이 어렵고 커스텀이 힘들다는 단점을 보완하기 위해서 자바스크립트로 구현해 보았습니다.
코드 풀이
<!-- 검색어 입력 폼 -->
<input type="text" id="search">
<!-- 자동완성 단어 리스트 -->
<div class="autocomplete"></div>
먼저 검색어를 입력받을 Input 요소와 자동완성을 시켜줄 리스트 요소를 하나 생성해 줍니다.
/* active 클래스를 가진 요소에 대해 */
.autocomplete > div.active {
background: #333;
color: #eee;
}
선택된 요소에(active 클래스를 가진 요소) 선택 표시를 해주기 위해서 CSS 스타일을 추가해 줍니다.
// 검색어 리스트
const dataList = [ "빨간색", "파란색", "노란색", "검정색" ];
// 검색 입력 요소
const $search = document.querySelector("#search");
// 검색어 리스트 요소
const $autoComplete = document.querySelector(".autocomplete");
// 현재 가르키고 있는 검색어 순번
let nowIndex = 0;
자동완성을 구현하기 위해서 필요 데이터를 선언해 줍니다.
- 자동완성에 사용될 검색 단어 리스트
- 입력 요소가 검색어를 보여줄 리스트 요소
- 리스트에서 커서를 가르쳐줄 현재 검색어 순번
// 단어 입력이 완료되었을 때
$search.onkeyup = (event) => {
const value = $search.value.trim();
// 리스트 필터링
const matchDataList = value
? dataList.filter((label) => label.includes(value))
: [];
switch (event.keyCode) {
// UP KEY
case 38:
nowIndex = Math.max(nowIndex - 1, 0);
break;
// DOWN KEY
case 40:
nowIndex = Math.min(nowIndex + 1, matchDataList.length - 1);
break;
// ENTER KEY
case 13:
document.querySelector("#search").value = matchDataList[nowIndex] || "";
// 초기화
nowIndex = 0;
matchDataList.length = 0;
break;
// 그외 다시 초기화
default:
nowIndex = 0;
break;
}
// 리스트 보여주기
showList(matchDataList, value, nowIndex);
};
keyup 이벤트를 통해서 입력값이 변했을 때 또는 Up Down Enter 키를 감지해 줍니다.
자동완성 된 검색어를 선택하는 용도로 Up, Down, Enter키를 감지해 줍니다.
// 검색어 입력값
const value = $search.value.trim();
// 리스트 필터링
const matchDataList = value
? dataList.filter((label) => label.includes(value))
: [];
검색어 데이터를 가져와주고 검색어에 해당하는 리스트로 필터링해 줍니다.
switch (event.keyCode) {
// UP KEY
case 38:
nowIndex = Math.max(nowIndex - 1, 0);
break;
// DOWN KEY
case 40:
nowIndex = Math.min(nowIndex + 1, matchDataList.length - 1);
break;
// ENTER KEY
case 13:
document.querySelector("#search").value = matchDataList[nowIndex] || "";
// 초기화
nowIndex = 0;
matchDataList.length = 0;
break;
// 그외 입력은 초기화
default:
nowIndex = 0;
break;
}
이제 키보드 이벤트에서 위쪽 화살표 키 또는 아래쪽 화살표 키를 눌렀음이 판별되면 아래와 같은 동작을 수행해 줍니다.
- Up - nowIndex - 1 수식을 적용하지만 0보다 작아진다면 0으로 지정
- Down - nowIndex + 1 수식을 적용하지만 보여줄 리스트 개수를 넘으면 안 됩니다.
// ENTER KEY
case 13:
document.querySelector("#search").value = matchDataList[nowIndex] || "";
// 초기화
nowIndex = 0;
matchDataList.length = 0;
break;
또한 Enter키를 눌렀을 때는 선택한 검색어로 대체되도록 matchDataList배열에서 선택한 단어를 지정해 대체해 주고 기존 데이터는 초기화해 줍니다.
// 리스트 보여주기
showList(matchDataList, value, nowIndex);
모든 작업이 끝나면 보여줄 리스트와 검색어, 현재 이동한 위치 인덱스를 인자값으로 보내줍니다.
const showList = (data, value, nowIndex) => {
// 정규식으로 변환
const regex = new RegExp(`(${value})`, "g");
$autoComplete.innerHTML = data
.map(
(label, index) => `
<div class='${nowIndex === index ? "active" : ""}'>
${label.replace(regex, "<mark>$1</mark>")}
</div>
`
)
.join("");
};
마지막으로 필터링된 데이터를 표시해 주는 작업만 남았습니다.
- 반복문을 돌려 현재 index가 nowIndex와 같으면 "active" 클래스를 부여해서 선택되었음을 표시해 줍니다.
'빨간색'.replace(/(빨)/g, '<mark>$1</mark>');
// <mark>빨</mark>간색
그리고 label을 표시해 주는 과정에서 변환시켜 준 정규식을 사용하면 특정 부분에 마커 표시를 해줄 수 있습니다.
초성검색 적용 예시 코드
초성검색 적용
[JS] 초성검색 구현하기
GitHub - hyukson/hangul-util: 한글 관련 자바스크립트 유틸 라이브러리입니다. 한글 관련 자바스크립트 유틸 라이브러리입니다. Contribute to hyukson/hangul-util development by creating an account on GitHub. github.com 'ha
gurtn.tistory.com
위 포스트를 참고하여 'hangul-util' 라이브러리 또는 공유드린 모든 코드가 존재하는 상태여야 합니다.
초성검색을 위한 코드가 준비되었다면, 변경할 코드는 총 두 군데가 존재합니다.
// 자동완성 필터링
const matchDataList = value
? dataList.filter((label) => includeByCho(value, label))
: [];
먼저 keyup 이벤트를 적용시킨 코드에서 자동완성 필터링 코드를 includes() 대신에 incldueByCho() 함수로 대체해 줍니다.
const showList = (data, value, nowIndex) => {
// 초성 정규식으로 변환
const regex = makeRegexByCho(value);
그리고 두 번째로 정규식으로 바꿔주는 부분을 makeRegexByCho() 함수로 대체시켜 주면 초성검색을 적용시킨 자동완성 기능을 만들 수 있습니다.