[JavaScript 30 Days Challenge] Type Ahead

yuza🍊·2021년 10월 15일
0
post-thumbnail

DAY 6-Type Ahead

CODE

구현 사항: 검색창(input box)에 문자를 입력하면 해당 문자가 들어간 미국의 도시를 나열해서 보여주기

1) 빈 배열 cities 선언 -> fetch() 함수 사용하여 endpoint로부터 데이터 fetch 후 복사하여 cities 배열에 push

const cities = [];
fetch(endpoint)
  .then((data) => data.json())
  .then((data) => cities.push(...data));
  • 이 때, endpoint로 요청 보낸 뒤 받을 수 있는 응답 데이터에 json() 메소드를 사용하여 promise 형태로 반환해야 함

2) findMatches() 함수 선언 -> cities 배열에 filter() 메소드 사용하여 필터링

function findMatches(wordToMatch, cities) {
	const target = new RegExp(wordToMatch, "gi");
	return cities.filter(
		(place) => place.city.match(target) || place.state.match(target)
	);
}
  • RegExp 객체 선언 후 target 변수에 할당 ("gi" 옵션 추가 -> g: 문자열 전체를 확인(전역 탐색), i: 문자열에서 대소문자 구분하지 않음)
  • cities 배열에서 city의 이름 또는 state 이름을 사용자가 입력한 단어 (wordToMatch)와 비교하여 그 단어가 city, state에 포함된 경우만 filtering 후 return 해야 함

3) displayMatches() 함수 선언 -> findMatches() 함수에 this.value(input된 value)와 cities(도시 정보가 담긴 json)을 매개변수로 넣기 -> 입력한 검색어와 일치하는 도시 array 반환받아서 matchedCities 변수에 할당

function displayMatches() {
	const matchedCities = findMatches(this.value, cities);
}

4) 화면에 보여질 때 사용자가 입력한 글자를 하이라이트해서 보여주기 위해 RegExp 객체 생성 후 this.value를 gi 옵션으로 변수 inputWord에 할당

function displayMatches() {
	const matchedCities = findMatches(this.value, cities);
	const inputWord = new RegExp(this.value, "gi");
	const html = matchedCities
		.map((place) => {
			const highlightedCity = place.city.replace(inputWord,
			`<span class="hl">${this.value}</span>`
			);
			const highlightedState = place.state.replace(inputWord,
			`<span class="hl">${this.value}</span>`
		);
	})
}
  • 변수 html 선언 후 matchedCities에 map() 메소드와 replace() 메소드 사용하여 array 내의 요소들 중 inputWord와 일치하는 부분을 으로 감싼 this.value로 replace한 뒤 highlightedCity 라는 변수에 할당

  • state도 동일한 방식으로 변수 highlightedState에 할당

5) map() 내부에서 위에서 생성한 highlightedCity, highlightedState와 도시의 인구수(place.population)를 span과 li 태그로 감싸서 return -> 사용자가 입력한 단어 부분이 하이라이트된 검색 결과 리스트가 html 변수에 할당됨

function displayMatches() {
	const matchedCities = findMatches(this.value, cities);
	const inputWord = new RegExp(this.value, "gi");
	const html = matchedCities
		.map((place) => {
			const highlightedCity = place.city.replace(inputWord,
			`<span class="hl">${this.value}</span>`
			);
			const highlightedState = place.state.replace(inputWord,
			`<span class="hl">${this.value}</span>`
			);
			return `
				<li>
					<span class="name">${highlightedCity}, ${highlightedState}</span>
					<span class="population">${place.population}</span>
				</li>
				`;
		})
}

6) join() 메소드를 사용하여 해당 li 태그 요소들을 전부 join 시킴 -> suggestions 변수 생성 후 .suggestions 요소 할당 -> suggestions.innerHTML = html을 통해 곰색 결과를 제안하는 li 태그 요소에 html을 할당

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

const searchInput = document.querySelector(".search");
const suggestions = document.querySelector(".suggestions");

searchInput.addEventListener("change", displayMatches);
searchInput.addEventListener("keyup", displayMatches);
  • 검색창 (.search)를 searchInput 변수에 할당 후 change, keyup 이벤트 발생 시 displayMatches 함수 실행되도록 event listen
profile
say hi to the world

0개의 댓글