143 lines
3.5 KiB
Vue
143 lines
3.5 KiB
Vue
<script setup>
|
|
import { ref, toRefs, computed, watch, onMounted } from 'vue';
|
|
import CreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue';
|
|
import VnSelectDialog from 'components/common/VnSelectDialog.vue';
|
|
import FetchData from 'components/FetchData.vue';
|
|
const emit = defineEmits(['update:modelValue', 'update:options']);
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
const { t } = useI18n();
|
|
const postcodesOptions = ref([]);
|
|
const postcodesRef = ref(null);
|
|
|
|
const $props = defineProps({
|
|
modelValue: {
|
|
type: [String, Number, Object],
|
|
default: null,
|
|
},
|
|
options: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
optionLabel: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
optionValue: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
filterOptions: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
isClearable: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
defaultFilter: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
});
|
|
|
|
const { options } = toRefs($props);
|
|
const myOptions = ref([]);
|
|
const myOptionsOriginal = ref([]);
|
|
|
|
const value = computed({
|
|
get() {
|
|
return $props.modelValue;
|
|
},
|
|
set(value) {
|
|
emit('update:modelValue', value);
|
|
},
|
|
});
|
|
|
|
onMounted(() => {
|
|
locationFilter($props.modelValue);
|
|
});
|
|
|
|
function setOptions(data) {
|
|
myOptions.value = JSON.parse(JSON.stringify(data));
|
|
myOptionsOriginal.value = JSON.parse(JSON.stringify(data));
|
|
}
|
|
setOptions(options.value);
|
|
|
|
watch(options, (newValue) => {
|
|
setOptions(newValue);
|
|
});
|
|
|
|
function showLabel(data) {
|
|
return `${data.code} - ${data.town}(${data.province}), ${data.country}`;
|
|
}
|
|
|
|
function locationFilter(search = '') {
|
|
if (
|
|
search &&
|
|
(search.includes('undefined') || search.startsWith(`${$props.modelValue} - `))
|
|
)
|
|
return;
|
|
let where = { search };
|
|
postcodesRef.value.fetch({ filter: { where }, limit: 30 });
|
|
}
|
|
|
|
function handleFetch(data) {
|
|
postcodesOptions.value = data;
|
|
}
|
|
</script>
|
|
<template>
|
|
<FetchData
|
|
ref="postcodesRef"
|
|
url="Postcodes/filter"
|
|
@on-fetch="(data) => handleFetch(data)"
|
|
/>
|
|
<VnSelectDialog
|
|
v-if="postcodesRef"
|
|
:option-label="(opt) => showLabel(opt) ?? 'code'"
|
|
:option-value="(opt) => opt.code"
|
|
v-model="value"
|
|
:options="postcodesOptions"
|
|
:label="t('Location')"
|
|
:placeholder="t('search_by_postalcode')"
|
|
@input-value="locationFilter"
|
|
:default-filter="true"
|
|
:input-debounce="300"
|
|
:class="{ required: $attrs.required }"
|
|
v-bind="$attrs"
|
|
emit-value
|
|
map-options
|
|
use-input
|
|
clearable
|
|
hide-selected
|
|
fill-input
|
|
>
|
|
<template #form>
|
|
<CreateNewPostcode @on-data-saved="locationFilter()" />
|
|
</template>
|
|
<template #option="{ itemProps, opt }">
|
|
<QItem v-bind="itemProps">
|
|
<QItemSection v-if="opt">
|
|
<QItemLabel>{{ opt.code }}</QItemLabel>
|
|
<QItemLabel caption>{{ showLabel(opt) }}</QItemLabel>
|
|
</QItemSection>
|
|
</QItem>
|
|
</template>
|
|
</VnSelectDialog>
|
|
</template>
|
|
<style lang="scss" scoped>
|
|
.add-icon {
|
|
cursor: pointer;
|
|
background-color: $primary;
|
|
border-radius: 50px;
|
|
}
|
|
</style>
|
|
|
|
<i18n>
|
|
en:
|
|
search_by_postalcode: Search by postalcode, town, province or country
|
|
es:
|
|
Location: Ubicación
|
|
search_by_postalcode: Buscar por código postal, ciudad o país
|
|
</i18n>
|