| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- <template>
- <DefaultSelect
- v-model="selectedState"
- v-bind="$attrs"
- use-input
- hide-selected
- fill-input
- clearable
- :options="stateOptions"
- :label
- :loading
- :placeholder
- @filter="filterFn"
- >
- <template #no-option>
- <q-item>
- <q-item-section class="text-grey">
- {{ $t("http.errors.no_records_found") }}
- </q-item-section>
- </q-item>
- </template>
- </DefaultSelect>
- </template>
- <script setup>
- import { getStates } from "src/api/state";
- import { ref, watch } from "vue";
- import { normalizeString } from "src/helpers/utils";
- import { useI18n } from "vue-i18n";
- import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
- const emit = defineEmits(["selectedCountryId"]);
- const { country, placeholder } = defineProps({
- country: {
- type: Object,
- required: false,
- default: () => ({
- label: "Brasil",
- value: 1,
- }),
- },
- placeholder: {
- type: String,
- default: () =>
- useI18n().t("common.actions.search") +
- " " +
- useI18n().t("ui.navigation.state"),
- },
- label: {
- type: String,
- default: () => useI18n().t("ui.navigation.state"),
- },
- });
- const selectedState = defineModel({ type: Object });
- const loading = ref(false);
- const baseOptions = ref([]);
- const stateOptions = ref([]);
- const ensureOnlyPossibleOptions = (country_id) => {
- stateOptions.value = country_id
- ? baseOptions.value.filter((s) => s.country_id === country_id)
- : baseOptions.value;
- };
- const filterFn = async (val, update) => {
- if (baseOptions.value.length === 0) {
- loading.value = true;
- try {
- const data = await getStates();
- baseOptions.value = data.map((s) => ({
- label: s.name,
- value: s.id,
- code: s.code,
- country_id: s.country_id,
- }));
- } catch (e) {
- console.error(e);
- } finally {
- loading.value = false;
- }
- }
- ensureOnlyPossibleOptions(country?.value);
- const needle = normalizeString(val);
- if (needle) {
- stateOptions.value = stateOptions.value.filter(
- (v) =>
- normalizeString(v.label).includes(needle) ||
- normalizeString(v.code).includes(needle),
- );
- }
- update();
- };
- const selectStateById = (id) => {
- if (selectedState.value?.value === id) return;
- selectedState.value = baseOptions.value.find((s) => s.value === id);
- };
- const selectStateByName = (name) => {
- if (selectedState.value?.label === name) return;
- selectedState.value = baseOptions.value.find((s) => s.label === name);
- };
- const selectStateByCode = (code) => {
- if (selectedState.value?.code === code) return;
- selectedState.value = baseOptions.value.find((s) => s.code === code);
- };
- watch(
- () => country,
- (value, oldValue) => {
- if (!oldValue) return;
- if (value?.value != oldValue?.value && value?.value != selectedState.value?.country_id) {
- selectedState.value = null;
- }
- if (value && baseOptions.value.length > 0) {
- ensureOnlyPossibleOptions(value.value);
- }
- },
- );
- watch(selectedState, () => {
- if (selectedState.value?.country_id) {
- emit("selectedCountryId", selectedState.value.country_id);
- }
- });
- defineExpose({
- selectStateById,
- selectStateByName,
- selectStateByCode,
- });
- </script>
|