Vue
by the94air
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/bootstrap-vue.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/bootstrap-vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<div id="app">
<b-container v-cloak>
<b-form @submit="handleSubmit" v-if="!success">
<b-form-row class="mb-4">
<b-col xl="4" lg="4" md="4" sm="12">
<b-form-select :options="options.years" v-model="form.year" size="lg" @change="handleYearChange" :disabled="disableAll"></b-form-select>
</b-col>
<b-col xl="4" lg="4" md="4" sm="12">
<b-form-select :options="options.makes" v-model="form.make" size="lg" :disabled="disableAll"></b-form-select>
</b-col>
<b-col xl="4" lg="4" md="4" sm="12">
<b-form-select :options="options.models" v-model="form.model" size="lg" :disabled="disableAll"></b-form-select>
</b-col>
<b-col xl="4" lg="4" md="4" sm="12">
<b-button type="submit" size="lg" variant="primary" block :disabled="disableAll"><span v-if="loading" class="loading">Please wait <span>.</span><span>.</span><span>.</span></span><span v-else>Submit</span></b-button>
</b-col>
<b-col xl="4" lg="4" md="4" sm="12">
<pre>{{ json }}</pre>
</b-col>
</b-form-row>
</b-form>
<b-row v-else>
<b-col>
<div style="text-align: center"><h1>Thank you!</h1></div>
</b-col>
</b-row>
</b-container>
</div>
CSS
body {
margin-top: 200px;
}
select, button, .loading {
margin-bottom: 15px;
}
.loading {
text-align: center;
}
.loading span {
animation-name: blink;
animation-duration: 1.4s;
animation-iteration-count: infinite;
animation-fill-mode: both;
}
.loading span:nth-child(2) {
animation-delay: .2s;
}
.loading span:nth-child(3) {
animation-delay: .4s;
}
@keyframes blink {
0% {
opacity: .2;
}
20% {
opacity: 1;
}
100% {
opacity: .2;
}
}
[v-cloak] {
display: none;
}
Vue
new Vue({
el: "#app",
watch: {
"form.year": function () {
this.prepareParams();
},
"form.make": function () {
this.prepareParams();
}
},
computed: {
json() {
return JSON.stringify(this.form, null, 2);
}
},
methods: {
handleSubmit(e) {
e.preventDefault();
// validate all fields
// send data to backend
if(this.form.year !== "" && this.form.make !== "" && this.form.model !== "") {
this.success = true;
}
},
handleYearChange() {
this.form.make = "";
this.form.model = "";
},
prepareParams() {
var self = this;
if(this.form.year !== "" && this.form.make !== "") {
self.loading = true;
self.disableAll = true;
var url = `https://vpic.nhtsa.dot.gov/api/vehicles/getmodelsformakeyear/make/${self.form.make}/modelyear/${self.form.year}?format=json`;
axios.get(url)
.then(function (response) {
var results = response.data.Results;
var models = [{ text: "Model...", value: "" }];
var modelsResults = results.map((result) => ({
text: result.Model_Name,
value: result.Model_Name
}));
models.push(...modelsResults);
self.options.models = models;
self.form.model = "";
self.disableAll = false;
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
self.loading = false;
});
}
},
},
data: {
loading: false,
disableAll: false,
success: false,
form: {
year: "",
make: "",
model: "",
},
options: {
years: [
{ text: "Year...", value: "" },
{ text: "2018", value: "2018" },
{ text: "2017", value: "2017" },
{ text: "2016", value: "2016" },
{ text: "2015", value: "2015" },
{ text: "2014", value: "2014" },
{...