본문 바로가기
JavaScript

[javaScript] filter()사용하여 커스텀 select 메뉴 검색 기능 만들기.

by teamnova 2023. 1. 11.

* 이 글은 이전 글인 classList를 사용한 커스텀 select 메뉴만들기 와 이어집니다.

 

안녕하세요! 오늘은 저번에 이어서 커스텀 select 메뉴를 완성해보도록하겠습니다.

국가같이 많은 양의 선택지가 주어져서 option이 길어지는 경우, filter() 메서드를 통해 검색을 구현해서 유저가 원하는 선택지를 손쉽게 찾을 수 있도록 해보겠습니다.

 

*filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환합니다.

그래서 이번에 진행할 내용은 아래와 같습니다. 

1. input에 값을 적을 때마다 일치하는 옵션 보여주기.

2. input에 값이 없으면(입력값이 없으면) 모든 옵션들 보여주기.

3.일치하는 값이 없으면 없다고 사용자에게 알려주기.

3.옵션 선택 시 선택 영역에 값 적용되며 아래 option 영역 보이지않기. 

 

custom_menu.html (이전 글과 동일)

<div class="wrapper">
  <div class="select">
    <span>나라를 선택해주세요</span>
    <span class="material-icons">expand_more</span>
  </div><!--select-->
  <div class="content">
    <div class="search-box">
      <span class="material-icons">search</span>     
      <input class="filter" type="text" placeholder="검색">
    </div><!--search box-->
    <ul class="options">
    </ul>
  </div><!--content-->
</div><!--wrapper-->
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

custom_menu.css (이전 글과 동일)

*{
  margin:0;
  padding:0;
  box-sizing: border-box;
}

.wrapper{
  width: 360px;
  margin:20px auto 0;
}
.select, .options li{
  display:flex;
  cursor:pointer;
  align-items:center;
}
.select{
  height:60px;
  padding:0 20px;
  background:#4285f4;
  border-radius:10px;
  color:#ffffff;
  justify-content:space-between;
}
.content{
  display:none;
  background:#ffffff;
  margin-top:5px;
  padding:15px;
  border-radius:10px;
}

.active .content {
  display:block;
}

.content .search-box{
  position: relative;
}
.search-box .material-icons{
  left:15px;
  line-height:53px;
  position: absolute;
}
.search-box input{
  height:53px;
  width:100%;
  outline:none;
  font-size:17px;
  padding:0 10px 0 43px;
  border: 1px solid #aabb;
  border-radius:10px;
}
.content .options{
  margin-top:10px;
  max-height:250px;
  overflow-y:auto;
}
.options::-webkit-scrollbar-track{
  backgound:#f1f1f1;
  border-radius:25px;
}

.options::-webkit-scrollbar-thumb{
  backgound:#ccc;
  border-radius:25px;
}

.options li{
  height:50px;
  padding:0 13px;
  border-radius:7px;
}
.options li:hover{
   background:#f2f2f2;
}

custom_menu2.js

const wrapper = document.querySelector('.wrapper');
const select = document.querySelector('.select');
const options = document.querySelector('.options');
const input = document.querySelector('.filter');//input element 

let countries = 
["가나","가봉","감비아","과테말라","그레나다","그리스","기니","네덜란드","대한민국"];

select.addEventListener('click',function(){
  let c = wrapper.className;
  wrapper.classList.toggle('active');
});

input.addEventListener('keyup',function(){//input에 글자를 적을 때마다 event발생.
  let arr = [];//사용자가 적은 값과 일치하는 국가명을 집어넣을 새로운 배열.
  let searchWord = input.value;//사용자 입력값
  
  if(searchWord.length>0){//사용자 입력값이 존재하는 경우
    
    arr= countries.filter(data=>{ //filter메서드를 사용해서 arr로 보내는데 
    return data.startsWith(searchWord);
  }).map(data=>`<li onclick="changeClickedName(this)">${data}</li>`).join("");
  //map을 사용해서 데이터를 <li>태그로 감싼 것처럼 처리함.
  //join함수를 사용해서 새배열(arr)에서 출력되는','를 없앰
    options.innerHTML= arr ? arr : '<p>조회된 나라가 없습니다.</p>';
    //조회되는 아이템이 없는 경우 보여주는 글귀 설정.
  }else{
  	//사용자 입력값이 존재하지않는 경우
    options.innerHTML="";//조회아이템이 없는 경우 보여주는 태그 비워주고
    addLi();//모든 국가명 보여주기
  }
  

});//input keyup event.

addLi();

function addLi(){
  countries.forEach(country=> {
    let li = `<li onclick="changeClickedName(this)">${country}</li>`;
    options.insertAdjacentHTML("beforeend",li);
  })
}

function changeClickedName(li){//옵션(국가명) 선택시
  input.value="";//input 초기화.
  addLi();//모든 국가명 보여주기
  wrapper.classList.remove('active');//classList사용해서 active 클래스명 삭제. 
  select.firstElementChild.innerText = li.innerText;//선택된 옵션 값이 선택영역에 적용되도록 함
}

 

자세한 내용은 아래 링크 추가적으로 참고 바랍니다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/map

 

Array.prototype.map() - JavaScript | MDN

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/join

 

Array.prototype.join() - JavaScript | MDN

join() 메서드는 배열의 모든 요소를 연결해 하나의 문자열로 만듭니다.

developer.mozilla.org