| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- <template>
- <q-select
- v-model="selectedState"
- v-bind="$attrs"
- use-input
- hide-selected
- fill-input
- clearable
- :options="stateOptions"
- :label
- :loading
- :placeholder="$t('common.actions.search') + ' ' + $t('ui.navigation.state')"
- :rules
- :error
- :error-message
- @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>
- </q-select>
- </template>
- <script setup>
- import { getStates } from "src/api/state";
- import { ref, onMounted, watch } from "vue";
- import { normalizeString } from "src/helpers/utils";
- import { useI18n } from "vue-i18n";
- const emit = defineEmits(["selectedCountryId"]);
- const { country, label, rules, initialId } = defineProps({
- country: {
- type: Object,
- required: false,
- default: () => {
- return {
- label: "Brasil",
- value: 1,
- };
- },
- },
- label: {
- type: String,
- default: () => useI18n().t("ui.navigation.state"),
- },
- rules: {
- type: Array,
- default: () => [],
- },
- initialId: {
- type: Number,
- required: false,
- default: null,
- },
- error: {
- type: Boolean,
- default: false,
- },
- errorMessage: {
- type: String,
- default: "",
- },
- });
- const selectedState = defineModel({ type: Object });
- const loading = ref(false);
- const baseOptions = ref([]);
- const stateOptions = ref([]);
- const filterFn = (val, update) => {
- ensureOnlyPossibleOptions(country?.value);
- const needle = normalizeString(val);
- if(val) {
- stateOptions.value = stateOptions.value.filter((v) => {
- return (
- normalizeString(v.label).includes(needle) ||
- normalizeString(v.code).includes(needle)
- );
- });
- } else {
- stateOptions.value = baseOptions.value;
- }
- update();
- };
- const selectStateById = async (id) => {
- if (selectedState.value?.value === id) {
- return;
- }
- selectedState.value = baseOptions.value.find((state) => state.value === id);
- };
- const selectStateByName = (name) => {
- if (selectedState.value?.label === name) {
- return;
- }
- selectedState.value = baseOptions.value.find((state) => state.label === name);
- };
- const selectStateByCode = (code) => {
- if (selectedState.value?.code === code) {
- return;
- }
- selectedState.value = baseOptions.value.find((state) => state.code === code);
- };
- const ensureOnlyPossibleOptions = (country_id) => {
- if (country_id) {
- stateOptions.value = baseOptions.value.filter(
- (state) => state.country_id === country_id,
- );
- } else {
- stateOptions.value = baseOptions.value;
- }
- };
- watch(
- () => country,
- (value, oldValue) => {
- if (
- value?.value != oldValue?.value &&
- value?.value != selectedState.value?.country_id
- ) {
- selectedState.value = null;
- }
- if (value) {
- ensureOnlyPossibleOptions(value.value);
- }
- },
- { immediate: true },
- );
- watch(selectedState, () => {
- if (selectedState.value?.country_id) {
- emit("selectedCountryId", selectedState.value.country_id);
- }
- });
- onMounted(async () => {
- try {
- loading.value = true;
- const baseStates = await getStates();
- baseOptions.value = baseStates.map((state) => ({
- label: state.name,
- value: state.id,
- code: state.code,
- country_id: state.country_id,
- }));
- stateOptions.value = baseOptions.value;
- if (initialId) {
- selectStateById(initialId);
- }
- } catch (e) {
- console.log(e);
- } finally {
- loading.value = false;
- }
- });
- defineExpose({
- selectStateById,
- selectStateByName,
- selectStateByCode,
- });
- </script>
|