Files
FlightsAPI/resources/js/Components/FlightsGoneBy/AirportSearchBox.vue
T
2026-04-04 18:10:01 +10:00

70 lines
2.0 KiB
Vue

<script setup lang="ts">
import { ref, nextTick } from 'vue'
import axios from 'axios'
const props = defineProps<{
prefilledOptions: { value: number, title: string, country_code: string }[]
errorMessages?: string[] | string
label?: string
}>()
const model = defineModel<{ value: number, title: string, country_code: string } | null>()
const airportOptions = ref(props.prefilledOptions ?? [])
const autocompleteRef = ref<any>(null)
const onFocus = () => {
nextTick(() => {
const input = autocompleteRef.value?.$el?.querySelector('input')
input?.select()
})
}
const searchAirports = async (query: string) => {
if (!query || query.length < 2) {
airportOptions.value = props.prefilledOptions ?? []
return
}
if (query === model.value?.title) return
const { data } = await axios.get('/search/airports', { params: { q: query } })
airportOptions.value = data
}
</script>
<template>
<v-autocomplete
ref="autocompleteRef"
v-model="model"
:label="label ?? 'Airport'"
:items="airportOptions"
:error-messages="errorMessages"
item-title="title"
@update:search="searchAirports"
@focus="onFocus"
hint="Search by IATA (3 letters), ICAO (4 letters), or airport/city name"
placeholder="SYD"
clearable
hide-no-data
return-object
:custom-filter="() => true"
>
<template #prepend-inner>
<span style="padding:0.5em">
<span v-if="model" :class="`fi fi-${model.country_code}`"></span>
</span>
</template>
<template #item="{ item, props: itemProps }">
<v-list-item v-bind="itemProps">
<template #prepend>
<span style="padding-right:1em">
<span :class="`fi fi-${item.country_code}`"></span>
</span>
</template>
</v-list-item>
</template>
</v-autocomplete>
</template>