Type Ahead

웹에서 정보를 받아와 Live Search 기능을 구현

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Type Ahead 👀</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <form class="search-form">
    <input type="text" class="search" placeholder="City or State">
    <ul class="suggestions">
      <li>Filter for a city</li>
      <li>or a state</li>
    </ul>
  </form>

  <script>
    const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
  </script>
</body>
</html>

목표

이번엔 스타일시트가 따로 빠져있는데 자바스크립트를 공부하는 목적이므로 따로 첨부는 하지 않음
우리는 검색창을 만들어서 도시나 주의 이름의 일부를 검색하면 도시, 주, 인구수를 실시간으로 보여주도록 만들 예정

과정

  1. 도시와 주의 이름과 인구수를 받아옴
  2. 검색시 일치하는 값을 찾아내는 함수를 만듦
  3. 위의 함수를 이용해 화면에 보여지게하는 함수를 만듦
  4. 인구수를 보기 편하게 콤마를 삽입하는 함수를 만들어줌
  5. 만든 함수를 통해 실시간으로 브라우저에 출력

코드 분석

  1. 도시와 주의 이름과 인구수를 받아옴

     const cities = [];
    
     fetch(endpoint)
       .then(blob => blob.json())
       .then(data => cities.push(...data));
    

cities라는 빈 배열을 생성하고, fetch()를 사용함
처음보는 함수인데 jQuery의 Ajax와 비슷한 느낌인 것 같다.
쉽게말해 이전에 기본코드에 담겨있던 endpoint json 파일을 파싱할때 JavaScript에서 fetch()를 사용하는 것 같다. 상세한 문법은 다음에 다시볼 때 정리해보도록 해야겠다

  1. 검색시 일치하는 값을 찾아내는 함수를 만듦
     function findMatches(wordToMatch, cities) {
       return cities.filter(place => {
         // here we need to figure out if the city or state matches what was searched
         const regex = new RegExp(wordToMatch, 'gi');
         return place.city.match(regex) || place.state.match(regex)
       });
     }
    
    검색시 단어가 일치하는 도시 또는 주를 반환하는 변수 regex를 만들고
    cities에 필터를 적용해 반환하도록 하는 findMatches 함수를 만든다
    이때 RegExp는 검색할때 패턴을 설정해 줄 수 있는 생성자이고, 'gi'는 전체에서 대소문자를 구분하지 않고 검색한다는 의미이다.
  1. 위의 함수를 이용해 화면에 보여지게하는 함수를 만듦

     function displayMatches() {
       const matchArray = findMatches(this.value, cities);
       const html = matchArray.map(place => {
         const regex = new RegExp(this.value, 'gi');
         const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
         const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
         return `
           <li>
             <span class="name">${cityName}, ${stateName}</span>
             <span class="population">${numberWithCommas(place.population)}</span>
           </li>
         `;
       }).join('');
       suggestions.innerHTML = html;
    }
    

    matchArray에 일치하는 값을 담고, html에 검색 후에 배열에서 일치하는 내용을 찾아
    cityName, stateName에 새로운 검색값이 들어간 html태그로 대체하도록 하고,
    새로운 리스트 태그를 반환하고 공백으로 서로를 연결하게 해서
    suggestions에 html내용을 스크립트로 삽입하는 이 모든과정을 displayMatches()함수에 담는다

  2. 인구수를 보기 편하게 콤마를 삽입하는 함수를 만들어줌

     function numberWithCommas(x) {
       return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
     }
    

    따로 알아볼 필요없이 킹갓Stackoverflow에서 가져온 코드

  3. 만든 함수를 통해 실시간으로 브라우저에 출력

     const searchInput = document.querySelector('.search');
     const suggestions = document.querySelector('.suggestions');
    
     searchInput.addEventListener('change', displayMatches);
     searchInput.addEventListener('keyup', displayMatches);
    

    searchInputsearch 클래스를 포함하는 요소들을 담고,
    suggestions에는 suggestions 클래스를 포함하는 요소들을 담는다.
    searchInputchange이벤트와 keyup이벤트가 실행될 때 displayMatches함수를 실행

    찾아본 내용, 알게된 내용들

fetch() - JavaScript의 Ajax와 비슷한 개념
... - ES6 문법으로 검색예정/잘모르겠다..주륵
match()

RegExp -생성자의 종류로, 특정 패턴에 맞는 텍스트를 위한 일반적인 표현식을 만들어 낸다.
사용법은 RegExp(pattern[, flags]) 로 사용하며 flags 종류는
g(전체에서 일치하는 모든문자 검색)
i(대소문자 구별하지 않음)
m(다중행에 적용)

끝!

'개발 > JavaScript30' 카테고리의 다른 글

8. Fun with HTML Canvas  (0) 2017.04.07
7. Array Cardio Day 2  (0) 2017.04.07
6. Type Ahead  (0) 2017.04.06
5. Flex Panel Gallery  (0) 2017.04.05
4. Array Cardio Day 1  (0) 2017.04.04
3. CSS Variables  (0) 2017.04.03

+ Recent posts