88< body >
99
1010 < form class ="search-form ">
11- < input type ="text " class ="search " placeholder ="City or State ">
11+ < input type ="text " class ="search " placeholder ="City or State " autofocus >
1212 < ul class ="suggestions ">
1313 < li > Filter for a city</ li >
1414 < li > or a state</ li >
1717< script >
1818const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json' ;
1919
20+ cities = [ ] ;
21+
22+ fetch ( endpoint )
23+ . then ( blob => blob . json ( ) )
24+ . then ( data => cities . push ( ...data ) ) ;
25+
26+ const searchBox = document . querySelector ( ".search" ) ;
27+ const searchForm = document . querySelector ( ".search-form" ) ;
28+ const suggestions = document . querySelector ( "form .suggestions" ) ;
29+
30+ searchBox . addEventListener ( 'keyup' , displayList ) ;
31+
32+ function displayList ( e ) {
33+ e . preventDefault ( ) ;
34+ if ( this . value . length > 0 ) {
35+ const matchArray = searchList ( this . value , cities ) ;
36+ const html = matchArray . map ( c => {
37+ const fullSearchText = `${ c . city } , ${ c . state } ` ;
38+ const indices = getMatchIndices ( fullSearchText , this . value ) ;
39+ const highlightedText = highlightLetters ( fullSearchText , indices ) ;
40+
41+ return (
42+ `<li>
43+ <span class="name">
44+ ${ highlightedText }
45+ </span>
46+ </li>` )
47+ } )
48+ . join ( '' ) ;
49+
50+ suggestions . innerHTML = html ;
51+ }
52+ else suggestions . innerHTML = "" ;
53+ }
54+
55+ function getMatchIndices ( text , searchText ) {
56+ let indices = [ ] ;
57+ let positionCounter = - 1 ;
58+
59+ searchText . split ( '' )
60+ . forEach ( e => {
61+ index = text . toLowerCase ( ) . indexOf ( e . toLowerCase ( ) , positionCounter ) ;
62+ if ( index >= 0 ) {
63+ indices . push ( index ) ;
64+ positionCounter = index + 1 ;
65+ }
66+ }
67+ ) ;
68+
69+ return indices ;
70+ }
71+
72+ function highlightLetters ( text , indices )
73+ {
74+ function highlightAtIndex ( text , index , replacementStart , replacementEnd ) {
75+ return text . substr ( 0 , index ) + replacementStart + text [ index ] + replacementEnd + text . substr ( index + 1 , text . length - 1 ) ;
76+ }
77+
78+ indices . reverse ( ) ;
79+ indices . forEach (
80+ index => text = highlightAtIndex ( text , index , `<span class="hl">` , `</span>` )
81+ ) ;
82+ return text ;
83+ }
84+
85+ function searchList ( wordToSearch , cities ) {
86+ const regex = new RegExp ( wordToSearch . split ( '' ) . join ( `.*` ) , 'gi' ) ;
87+ return cities . filter ( c => {
88+ const fullSearchText = `${ c . city } , ${ c . state } ` ;
89+ return fullSearchText . match ( regex ) ;
90+ } ) ;
91+ }
2092</ script >
2193 </ body >
2294</ html >
95+
0 commit comments