|
|
@@ -28,11 +28,12 @@
|
|
|
<script setup>
|
|
|
import { getCities } from "src/api/city";
|
|
|
import { ref, onMounted, watch } from "vue";
|
|
|
+import { normalizeString } from "src/helpers/utils";
|
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
|
|
const emit = defineEmits(["selectedStateId"]);
|
|
|
|
|
|
-const { state, label, rules, initialId } = defineProps({
|
|
|
+const { state, label, rules, initialId, country } = defineProps({
|
|
|
// This country prop is here for future use, maybe
|
|
|
country: {
|
|
|
type: Object,
|
|
|
@@ -72,32 +73,21 @@ const { state, label, rules, initialId } = defineProps({
|
|
|
},
|
|
|
});
|
|
|
|
|
|
-const selectedCity = defineModel();
|
|
|
+const selectedCity = defineModel({ type: Object });
|
|
|
|
|
|
const loading = ref(false);
|
|
|
-const filteredCities = ref([]);
|
|
|
-const baseCities = ref([]);
|
|
|
+const baseOptions = ref([]);
|
|
|
const cityOptions = ref([]);
|
|
|
|
|
|
const filterFn = async (val, update) => {
|
|
|
- if (!val) {
|
|
|
- cityOptions.value = filteredCities.value.map((city) => ({
|
|
|
- label: city.name,
|
|
|
- value: city.id,
|
|
|
- state_id: city.state_id,
|
|
|
- }));
|
|
|
- } else {
|
|
|
- const needle = val.toLowerCase();
|
|
|
- const cities = filteredCities.value.filter(
|
|
|
- (v) => v.name.toLowerCase().indexOf(needle) > -1,
|
|
|
+ ensureOnlyPossibleOptions(country?.value, state?.value);
|
|
|
+ const needle = normalizeString(val);
|
|
|
+ cityOptions.value = cityOptions.value.filter((v) => {
|
|
|
+ return (
|
|
|
+ normalizeString(v.label).includes(needle) ||
|
|
|
+ normalizeString(v.code).includes(needle)
|
|
|
);
|
|
|
- cityOptions.value = cities.map((city) => ({
|
|
|
- label: city.name,
|
|
|
- value: city.id,
|
|
|
- state_id: city.state_id,
|
|
|
- }));
|
|
|
- }
|
|
|
-
|
|
|
+ });
|
|
|
update();
|
|
|
};
|
|
|
|
|
|
@@ -105,14 +95,28 @@ const selectCityByName = (name) => {
|
|
|
if (selectedCity.value?.label === name) {
|
|
|
return;
|
|
|
}
|
|
|
- selectedCity.value = cityOptions.value.find((city) => city.label === name);
|
|
|
+ selectedCity.value = baseOptions.value.find((city) => city.label === name);
|
|
|
};
|
|
|
|
|
|
const selectCityById = (id) => {
|
|
|
if (selectedCity.value?.value === id) {
|
|
|
return;
|
|
|
}
|
|
|
- selectedCity.value = cityOptions.value.find((city) => city.value === id);
|
|
|
+ selectedCity.value = baseOptions.value.find((city) => city.value === id);
|
|
|
+};
|
|
|
+
|
|
|
+const ensureOnlyPossibleOptions = (country_id, state_id) => {
|
|
|
+ if (state_id) {
|
|
|
+ cityOptions.value = baseOptions.value.filter((city) => {
|
|
|
+ if (country_id) {
|
|
|
+ return city.country_id === country_id && city.state_id === state_id;
|
|
|
+ }
|
|
|
+ return city.state_id === state_id;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (!!state_id && !country_id) {
|
|
|
+ cityOptions.value = baseOptions.value;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
watch(
|
|
|
@@ -125,21 +129,7 @@ watch(
|
|
|
selectedCity.value = null;
|
|
|
}
|
|
|
if (value) {
|
|
|
- filteredCities.value = baseCities.value.filter(
|
|
|
- (city) => city.state_id === value.value,
|
|
|
- );
|
|
|
- cityOptions.value = filteredCities.value.map((city) => ({
|
|
|
- label: city.name,
|
|
|
- value: city.id,
|
|
|
- state_id: city.state_id,
|
|
|
- }));
|
|
|
- } else {
|
|
|
- filteredCities.value = baseCities.value;
|
|
|
- cityOptions.value = baseCities.value.map((city) => ({
|
|
|
- label: city.name,
|
|
|
- value: city.id,
|
|
|
- state_id: city.state_id,
|
|
|
- }));
|
|
|
+ ensureOnlyPossibleOptions(country?.value, value.value);
|
|
|
}
|
|
|
},
|
|
|
{ immediate: true },
|
|
|
@@ -154,13 +144,13 @@ watch(selectedCity, () => {
|
|
|
onMounted(async () => {
|
|
|
try {
|
|
|
loading.value = true;
|
|
|
- baseCities.value = await getCities();
|
|
|
- filteredCities.value = baseCities.value;
|
|
|
- cityOptions.value = baseCities.value.map((city) => ({
|
|
|
+ const baseCities = await getCities();
|
|
|
+ baseOptions.value = baseCities.map((city) => ({
|
|
|
label: city.name,
|
|
|
value: city.id,
|
|
|
state_id: city.state_id,
|
|
|
}));
|
|
|
+ cityOptions.value = baseOptions.value;
|
|
|
if (initialId) {
|
|
|
selectCityById(initialId);
|
|
|
}
|