Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b146c48

Browse files
Add Day6: Type Ahead Search
1 parent 9bddb56 commit b146c48

File tree

4 files changed

+164
-0
lines changed

4 files changed

+164
-0
lines changed

‎src/components/Day6/Home.vue‎

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<template>
2+
<div class="flex flex-col pt-10 h-screen bg-grey-lightest px-5" @click='hideSuggestions'>
3+
<div class="input">
4+
<div>
5+
<span class="absolute pt-3 pl-4"><i class="text-lg text-blue fas fa-search"></i></span>
6+
<div id="searchbox" @click="focusSearch" v-show="showLabel && !input" class="label">Type here</div>
7+
<input ref="search" id="searchbox" @keyup="startSearch" @blur="blured" @focus.prevent="focused" class="input-box" v-model="input">
8+
</div>
9+
<div v-show="showSuggestions">
10+
<div class="autocomplete">
11+
<div v-for="place in suggestions" :key="place.rank" @click="selectPlace(place)">
12+
{{place.city}}, {{place.state}}
13+
<span class="float-right p-0">{{place.population}}</span>
14+
</div>
15+
</div>
16+
</div>
17+
</div>
18+
<div v-if="place.rank" class="block p-3 text-left self-center my-5 shadow rounded bg-white max-w-xs w-2/3">
19+
<div class="text-md">{{place.city}}</div>
20+
<div>
21+
<span class="align-bottom text-xl">{{place.state}}</span><span class="align-bottom text-sm float-right">{{place.population}}</span>
22+
</div>
23+
</div>
24+
</div>
25+
</template>
26+
27+
<script>
28+
export default {
29+
name: "day6",
30+
data() {
31+
return {
32+
input: "",
33+
showLabel: true,
34+
showSuggestions: true,
35+
inputClass: {
36+
input: true,
37+
focused: true
38+
},
39+
cities: [],
40+
suggestions: [],
41+
place: {}
42+
};
43+
},
44+
methods: {
45+
startSearch() {
46+
if (this.input) {
47+
this.suggestions = this.cities.filter(place => {
48+
const regex = new RegExp(this.input, "gi");
49+
return place.city.match(regex) || place.state.match(regex);
50+
});
51+
this.suggestions = this.suggestions.slice(0, 10);
52+
} else {
53+
this.suggestions = [];
54+
}
55+
},
56+
focused() {
57+
this.showLabel = false;
58+
this.showSuggestions = true;
59+
},
60+
blured() {
61+
this.showLabel = true;
62+
},
63+
selectPlace(place) {
64+
this.place = place;
65+
this.input = "";
66+
this.showLabel = true;
67+
this.showSuggestions = false;
68+
this.suggestions = [];
69+
},
70+
hideSuggestions(e) {
71+
if (e.target.id !== "searchbox") {
72+
this.showSuggestions = false;
73+
}
74+
},
75+
focusSearch() {
76+
this.$refs.search.focus();
77+
this.showLabel = false;
78+
this.showSuggestions = true;
79+
}
80+
},
81+
mounted() {
82+
fetch(
83+
"https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json"
84+
)
85+
.then(blob => blob.json())
86+
.then(data => {
87+
this.cities.push(...data);
88+
this.cities.forEach(place => {
89+
place.population = place.population
90+
.toString()
91+
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
92+
return place;
93+
});
94+
});
95+
}
96+
};
97+
</script>
98+
99+
<style lang="postcss" scoped>
100+
.input {
101+
@apply w-full max-w-lg mx-auto shadow bg-white;
102+
border-radius: 2rem;
103+
}
104+
105+
.autocomplete > div:first-child {
106+
@apply bg-grey-lighter;
107+
}
108+
109+
.autocomplete {
110+
border-bottom-left-radius: 2em;
111+
border-bottom-right-radius: 2em;
112+
}
113+
114+
.autocomplete > div:last-child {
115+
border-bottom-left-radius: 2em;
116+
border-bottom-right-radius: 2em;
117+
}
118+
119+
.autocomplete > div:hover {
120+
@apply bg-grey-light;
121+
}
122+
123+
.autocomplete div {
124+
@apply py-3 px-10 text-left cursor-pointer;
125+
}
126+
127+
.label {
128+
@apply absolute py-3 px-10 text-lg text-grey-darker;
129+
}
130+
131+
.search-icon {
132+
@apply z-50 border-grey-light border cursor-pointer px-3;
133+
@apply text-blue inline-block absolute py-2 pin-r rounded-full bg-white;
134+
}
135+
136+
.input-box {
137+
@apply text-grey-darkest bg-white w-full py-3 text-lg px-10 outline-none z-50;
138+
border-radius: 2rem;
139+
}
140+
</style>

‎src/router.js‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ export default new Router({
3333
path: "/day5",
3434
name: "day5",
3535
component: () => import(/* webpackChunkName: "day5" */ "./views/Day5.vue")
36+
},
37+
{
38+
path: "/day6",
39+
name: "day6",
40+
component: () => import(/* webpackChunkName: "day6" */ "./views/Day6.vue")
3641
}
3742
]
3843
});

‎src/views/Day6.vue‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<template>
2+
<div class="h-full">
3+
<home />
4+
</div>
5+
</template>
6+
7+
<script>
8+
import Home from "@/components/Day6/Home.vue";
9+
export default {
10+
name: "day6",
11+
components: {
12+
Home
13+
}
14+
};
15+
</script>
16+
17+
<style>
18+
</style>

‎src/views/Home.vue‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<router-link class="no-underline btn" to="/day2">02. Clock</router-link>
1616
<router-link class="no-underline btn" to="/day3">03. CSS Variables</router-link>
1717
<router-link class="no-underline btn" to="/day5">05. Flex Gallery</router-link>
18+
<router-link class="no-underline btn" to="/day6">05. Type Ahead Search</router-link>
1819
</div>
1920
</div>
2021
</div>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /