1+ <template >
2+ <div
3+ class =" search"
4+ :class =" {
5+ 'open': openSuggestion
6+ }" >
7+ <div class =" search-container" >
8+ <div class =" countries-wrapper" >
9+ <input
10+ ref =" countries"
11+ type =" text"
12+ v-model =" country"
13+ @keydown.enter =" enter"
14+ @keydown.down =" down"
15+ @keydown.up =" up"
16+ @input =" change"
17+ />
18+ </div >
19+ <div
20+ class =" provinces-wrapper"
21+ :class =" {
22+ 'is-show': provinces && provinces.length
23+ }" >
24+ <select ref =" provinces" >
25+ <option
26+ v-for =" (province, index) in provinces"
27+ :key =" index"
28+ :label =" province"
29+ :value =" province" />
30+ </select >
31+ </div >
32+ <button @click =" onSearch" >Search</button >
33+ </div >
34+ <ul class =" dropdown-menu" >
35+ <li
36+ v-for =" (suggestion, index) in matches"
37+ :key =" index"
38+ v-bind:class =" {'active': isActive(index)}"
39+ @click =" suggestionClick(index)"
40+ >
41+ <span >{{ suggestion }}</span >
42+ </li >
43+ </ul >
44+ </div >
45+ </template >
46+
47+ <script >
48+ export default {
49+ name: ' Search' ,
50+ props: {
51+ suggestions: {
52+ type: Object ,
53+ required: true
54+ },
55+ selection: {
56+ type: String ,
57+ required: true
58+ }
59+ },
60+ computed: {
61+ setSelection: {
62+ get () {
63+ return this .selection
64+ },
65+ set (newSelect ) {
66+ this .country = newSelect
67+ this .provinces = this .suggestions [newSelect].filter (_ => _)
68+ }
69+ },
70+ matches () {
71+ const countries = Object .keys (this .suggestions )
72+ const lowerCased = this .country .toLowerCase ()
73+ return countries .filter (str => {
74+ return str .toLowerCase ().indexOf (lowerCased) >= 0
75+ })
76+ },
77+ openSuggestion () {
78+ return (
79+ this .country !== ' ' && this .matches .length != 0 && this .open === true
80+ )
81+ }
82+ },
83+ data () {
84+ return {
85+ open: false ,
86+ current: 0 ,
87+ country: ' ' ,
88+ provinces: ' '
89+ }
90+ },
91+ methods: {
92+ enter () {
93+ this .setSelection = this .matches [this .current ]
94+ this .open = false
95+ this .$nextTick (_ => {
96+ if (this .$refs .provinces ) this .$refs .provinces .focus ()
97+ })
98+ },
99+ up () {
100+ if (this .current > 0 ) this .current --
101+ },
102+ down () {
103+ if (this .current < this .matches .length - 1 ) this .current ++
104+ },
105+ isActive (index ) {
106+ return index === this .current
107+ },
108+ change () {
109+ if (! this .open ) {
110+ this .open = true
111+ this .current = 0
112+ }
113+ },
114+ suggestionClick (index ) {
115+ this .setSelection = this .matches [index]
116+ this .open = false
117+ this .$nextTick (_ => {
118+ if (this .$refs .provinces ) this .$refs .provinces .focus ()
119+ })
120+ },
121+ onSearch () {
122+ this .$store .dispatch (' getCasesByCountry' , {
123+ country: this .country ,
124+ province: this .$refs .provinces .value
125+ })
126+ }
127+ }
128+ }
129+ </script >
130+
131+
132+ <style lang="scss" scoped>
133+ .search {
134+ position : relative ;
135+
136+ & .open {
137+
138+ .dropdown-menu {
139+ display : block ;
140+ }
141+ }
142+
143+ .countries-wrapper {
144+ input {
145+ margin : 0 ;
146+ padding : 0 ;
147+ border : 0 ;
148+ border-bottom : 1px solid #ffffff ;
149+ color : #ffffff ;
150+ background-color : transparent ;
151+ outline : none ;
152+ }
153+ }
154+
155+ .provinces-wrapper {
156+ display : none ;
157+
158+ & .is-show {
159+ display : block ;
160+ }
161+ }
162+
163+ .dropdown-menu {
164+ display : none ;
165+ width : 100% ;
166+ }
167+ }
168+ </style >
0 commit comments