|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | + <meta charset="UTF-8"> |
| 5 | + <title>Type Ahead 👀</title> |
| 6 | + <link rel="stylesheet" href="style.css"> |
| 7 | +</head> |
| 8 | +<body> |
| 9 | + |
| 10 | + <form class="search-form"> |
| 11 | + <input type="text" class="search" placeholder="City or State"> |
| 12 | + <ul class="suggestions"> |
| 13 | + <li>Filter for a city</li> |
| 14 | + <li>or a state</li> |
| 15 | + </ul> |
| 16 | + </form> |
| 17 | +<script> |
| 18 | +const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json'; |
| 19 | + |
| 20 | +const cities = []; |
| 21 | + |
| 22 | +fetch(endpoint) |
| 23 | + .then(blob => blob.json()) //fetch is new browser API. Returns a 'promise'. Then methods returns a set of data with no formatting otherwise hence calling it "blob" |
| 24 | + .then(data => cities.push(...data)) //... means spread and is new is ES6. Regular push with spread would nest all objects in the 'data' as the first index of 'cities', not make an individual array entry for each object. |
| 25 | + //newlines don't interrupt here: this is chain .then methods to eventually extract json data and enter each object as an entry into the cities array |
| 26 | + //note also that you can push things to a variable assigned with const, even though you cant reassign variables |
| 27 | + |
| 28 | +function findMatches(wordToMatch, cities) { |
| 29 | + return cities.filter(place => { |
| 30 | + //here we need to figure out if the city/state matches what was searched |
| 31 | + //we'll need some regex to verify a match, but we need the regex to contain a variable (whatever the user searches) |
| 32 | + const regex = new RegExp(wordToMatch, 'gi'); |
| 33 | + return place.city.match(regex) || place.state.match(regex) |
| 34 | + }); |
| 35 | +} |
| 36 | + |
| 37 | +function numberWithCommas(x) { |
| 38 | + return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); |
| 39 | +} //crazy regex, stack overflox to the rescue |
| 40 | + |
| 41 | +function displayMatches () { |
| 42 | + const matchArray = findMatches(this.value, cities); |
| 43 | + const html = matchArray.map(place => { |
| 44 | + const regex = RegExp(this.value, 'gi'); |
| 45 | + const cityName = place.city.replace(regex,`<span class="hl">${this.value}</span>`); |
| 46 | + const stateName = place.state.replace(regex,`<span class="hl">${this.value}</span>`); |
| 47 | + return ` |
| 48 | + <li> |
| 49 | + <span class="name">${cityName} ${stateName}</span> |
| 50 | + <span class="population">${numberWithCommas(place.population)}</span> |
| 51 | + </li> |
| 52 | + `; |
| 53 | + }).join(''); |
| 54 | + suggestions.innerHTML = html; |
| 55 | +} |
| 56 | + |
| 57 | +const searchInput = document.querySelector('.search'); |
| 58 | +const suggestions = document.querySelector('.suggestions'); |
| 59 | + |
| 60 | +searchInput.addEventListener('change',displayMatches); |
| 61 | +searchInput.addEventListener('keyup',displayMatches); |
| 62 | + |
| 63 | +</script> |
| 64 | + </body> |
| 65 | +</html> |
0 commit comments