|
|
@@ -0,0 +1,112 @@
|
|
|
+<template>
|
|
|
+ <main>
|
|
|
+ <v-autocomplete
|
|
|
+ v-model="model"
|
|
|
+ :value="data"
|
|
|
+ :items="items"
|
|
|
+ :loading="isLoading"
|
|
|
+ :search-input.sync="search"
|
|
|
+ hide-no-data
|
|
|
+ hide-selected
|
|
|
+ item-text="textDisplay"
|
|
|
+ :item-value="itemValue"
|
|
|
+ :label="$t(label_field)"
|
|
|
+ :placeholder="$t('start_your_research')"
|
|
|
+ prepend-icon="mdi-magnify"
|
|
|
+ :return-object="returnObject"
|
|
|
+ ></v-autocomplete>
|
|
|
+
|
|
|
+ </main>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts">
|
|
|
+ import {defineComponent, computed, watch, ref, useContext, onUnmounted} from '@nuxtjs/composition-api'
|
|
|
+ import {QUERY_TYPE} from "~/types/enums";
|
|
|
+ import * as _ from "lodash";
|
|
|
+
|
|
|
+ export default defineComponent({
|
|
|
+ props: {
|
|
|
+ label:{
|
|
|
+ type: String,
|
|
|
+ required: false
|
|
|
+ },
|
|
|
+ field:{
|
|
|
+ type: String,
|
|
|
+ required: false
|
|
|
+ },
|
|
|
+ data: {
|
|
|
+ type: String,
|
|
|
+ required: false
|
|
|
+ },
|
|
|
+ readOnly: {
|
|
|
+ type: Boolean,
|
|
|
+ required: false
|
|
|
+ },
|
|
|
+ itemValue:{
|
|
|
+ type: String,
|
|
|
+ default: 'id'
|
|
|
+ },
|
|
|
+ itemText:{
|
|
|
+ type: Array,
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ returnObject:{
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setup(props){
|
|
|
+ const {$dataProvider} = useContext();
|
|
|
+
|
|
|
+ const search = ref(null);
|
|
|
+ const model = ref(null);
|
|
|
+ const count = ref(0);
|
|
|
+ const entries = ref([]);
|
|
|
+ const isLoading = ref(false);
|
|
|
+
|
|
|
+ const items = computed(() => {
|
|
|
+ return entries.value.map(entry => {
|
|
|
+ const textDisplay:Array<string> = []
|
|
|
+ for (const text of props.itemText){
|
|
|
+ textDisplay.push(entry[text as string])
|
|
|
+ }
|
|
|
+ return Object.assign({}, entry, { textDisplay: textDisplay.join(' ') })
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ const unwatch = watch(search, _.debounce(async (research) => {
|
|
|
+ // Items have already been requested
|
|
|
+ if (isLoading.value) return
|
|
|
+
|
|
|
+ isLoading.value = true
|
|
|
+
|
|
|
+ let response = await $dataProvider.invoke({
|
|
|
+ type: QUERY_TYPE.DEFAULT,
|
|
|
+ url: `gps-coordinate-searching?city=${research}`
|
|
|
+ })
|
|
|
+
|
|
|
+ count.value = response.length
|
|
|
+ entries.value = response
|
|
|
+ isLoading.value = false
|
|
|
+ }, 500))
|
|
|
+
|
|
|
+ onUnmounted(()=>{
|
|
|
+ unwatch()
|
|
|
+ })
|
|
|
+
|
|
|
+ return {
|
|
|
+ label_field : props.label ?? props.field,
|
|
|
+ count,
|
|
|
+ isLoading,
|
|
|
+ items,
|
|
|
+ search,
|
|
|
+ model
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+
|
|
|
+</style>
|