CountrySelect.vue 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <template>
  2. <q-select
  3. v-model="selectedCountry"
  4. v-bind="$attrs"
  5. use-input
  6. hide-selected
  7. fill-input
  8. clearable
  9. :options="countryOptions"
  10. :label="label"
  11. :loading="loading"
  12. :placeholder="$t('common.actions.search') + ' ' + $t('ui.navigation.country')"
  13. :rules="rules"
  14. @filter="filterFn"
  15. >
  16. <template #no-option>
  17. <q-item>
  18. <q-item-section class="text-grey">
  19. {{ $t("http.errors.no_records_found") }}
  20. </q-item-section>
  21. </q-item>
  22. </template>
  23. </q-select>
  24. </template>
  25. <script setup>
  26. import { getCountries } from "src/api/country";
  27. import { ref, onMounted } from "vue";
  28. import { useI18n } from "vue-i18n";
  29. const { label, rules } = defineProps({
  30. label: {
  31. type: String,
  32. default: () => useI18n().t("ui.navigation.country"),
  33. },
  34. rules: {
  35. type: Array,
  36. default: () => [],
  37. },
  38. });
  39. const selectedCountry = defineModel();
  40. const loading = ref(false);
  41. const baseCountry = ref([]);
  42. const countries = ref([]);
  43. const countryOptions = ref([]);
  44. const filterFn = async (val, update) => {
  45. const filter = () => {
  46. const needle = val.toLowerCase();
  47. countries.value = baseCountry.value.filter((v) =>
  48. v.name.toLowerCase().includes(needle),
  49. );
  50. countryOptions.value = countries.value.map((country) => ({
  51. label: country.name,
  52. value: country.id,
  53. }));
  54. };
  55. update(filter);
  56. };
  57. const selectCountryByName = (name) => {
  58. if (selectedCountry.value && selectedCountry.value.label === name) return;
  59. selectedCountry.value = countryOptions.value.find(
  60. (country) => country.label === name,
  61. );
  62. };
  63. const selectCountryById = (id) => {
  64. if (selectedCountry.value && selectedCountry.value.id === id) return;
  65. selectedCountry.value = countryOptions.value.find(
  66. (country) => country.value === id,
  67. );
  68. };
  69. onMounted(async () => {
  70. try {
  71. loading.value = true;
  72. baseCountry.value = await getCountries();
  73. countryOptions.value = baseCountry.value.map((country) => ({
  74. label: country.name,
  75. value: country.id,
  76. }));
  77. } catch (e) {
  78. console.log(e);
  79. } finally {
  80. loading.value = false;
  81. }
  82. });
  83. defineExpose({
  84. selectCountryByName,
  85. selectCountryById,
  86. });
  87. </script>