Skip to content

Commit 3164320

Browse files
authored
Prevent closing the country popup when no result (#30)
* Prevent closing the country popup when no result * search text as a prop * new prop
1 parent f6aecac commit 3164320

File tree

4 files changed

+27
-6
lines changed

4 files changed

+27
-6
lines changed

dev/serve.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div id="app">
33
<div class="row">
44
<div class="col-3 offset-3 q-mt-lg">
5-
<vue3-q-tel-input use-icon v-model:tel="input" searchText="Search using code/country" dense filled default-country="de" @country="c => (country = c)" />
5+
<vue3-q-tel-input use-icon v-model:tel="input" searchText="Search using code/country" dense filled default-country="de" @country="c => (country = c)" no-results-text="Sample here" />
66
</div>
77
</div>
88
<div>entered telephone number : {{ input }}</div>

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ _example_
122122
| dropdown-options | Obejct | No | The props availalbe for the [Quasar Select](https://quasar.dev/vue-components/select) |
123123
| eager-validate | Boolean | No | Set to true if the validation needs not be run on loading |
124124
| use-icon | Boolean | No | Set to use the emoji icon instead of the default flag images |
125+
| no-results-text | String | No | Set a string when the search results nothing, default: 'No results found' |
125126

126127
#### Events
127128

src/component/CountrySelection.vue

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<q-select
33
:model-value="country"
44
:options="countryOptions"
5+
:option-disable="isDisabled"
56
hide-bottom-space
67
hide-dropdown-icon
78
borderless
@@ -14,9 +15,9 @@
1415
>
1516
<template v-slot:option="scope">
1617
<div class="flex items-center q-pa-xs mdi-border-bottom no-wrap" v-bind="scope.itemProps">
17-
<span :class="!useIcon ? ['v3q_tel__flag', scope.opt.iso2.toLowerCase()] : 'q-mr-sm'">{{ useIcon ? scope.opt.emoji : '' }}</span>
18-
<span class="q-ml-sm text-no-wrap">(+{{ scope.opt.dialCode }})</span>
19-
<span class="q-ml-sm text-no-wrap ellipsis">{{ scope.opt.name }}</span>
18+
<span v-if="!!scope.opt.iso2" :class="!useIcon ? ['v3q_tel__flag', scope.opt.iso2.toLowerCase()] : 'q-mr-sm'">{{ useIcon ? scope.opt.emoji : '' }}</span>
19+
<span v-if="!!scope.opt.dialCode" class="q-ml-sm text-no-wrap">(+{{ scope.opt.dialCode }})</span>
20+
<span :class="['q-ml-sm text-no-wrap ellipsis', { 'disabled full-width text-center': scope.opt.disabled }]">{{ scope.opt.name }}</span>
2021
</div>
2122
<q-separator />
2223
</template>
@@ -49,6 +50,8 @@ import countries, { filterCountries } from './countries';
4950
import { Country } from './types';
5051
import { QSelect, QIcon, QSeparator, QInput } from 'quasar';
5152
53+
type CountryOption = Country & { disabled?: boolean };
54+
5255
export default defineComponent({
5356
name: 'country-selection',
5457
components: {
@@ -61,6 +64,7 @@ export default defineComponent({
6164
country: { type: Object as PropType<Country>, required: true },
6265
searchText: { type: String, default: () => 'Search' },
6366
searchIcon: { type: String, default: () => 'search' },
67+
noResultsText: { type: String, default: () => 'No results found' },
6468
useIcon: { type: Boolean, default: () => false },
6569
},
6670
emits: ['countryChanged', 'update:country'],
@@ -75,7 +79,7 @@ export default defineComponent({
7579
},
7680
setup() {
7781
const search_text: Ref<string> = ref('');
78-
const countryOptions: Ref<Country[]> = ref([]);
82+
const countryOptions: Ref<CountryOption[]> = ref([]);
7983
return {
8084
search_text,
8185
countryOptions,
@@ -87,12 +91,26 @@ export default defineComponent({
8791
methods: {
8892
performSearch() {
8993
const needle = this.search_text.toLowerCase().trim();
90-
this.countryOptions = needle === '' ? [...countries] : filterCountries(needle);
94+
const newCountries: CountryOption[] = needle === '' ? [...countries] : filterCountries(needle);
95+
if (newCountries.length === 0)
96+
newCountries.push({
97+
name: this.noResultsText,
98+
dialCode: '',
99+
iso2: '',
100+
disabled: true,
101+
});
102+
this.countryOptions.splice(0, this.countryOptions.length, ...newCountries);
91103
},
92104
countryChanged(val: Country) {
93105
this.$emit('update:country', val);
94106
this.$emit('countryChanged', val);
95107
},
108+
isDisabled(option: unknown) {
109+
if (typeof option === 'string') {
110+
return false;
111+
}
112+
return !!(option as CountryOption).disabled;
113+
},
96114
},
97115
});
98116
</script>

src/component/Index.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
:readonly="readonly"
1111
:disable="disable"
1212
:dense="dense"
13+
:no-results-text="noResultsText"
1314
v-bind="dropdownOptions"
1415
class="no-border-field-before no-padding-field font-reduced-input-adon"
1516
>
@@ -44,6 +45,7 @@ export default defineComponent({
4445
searchText: { type: String, default: () => 'Search' },
4546
searchIcon: { type: String, default: () => 'search' },
4647
dropdownOptions: { type: Object, default: () => ({}) },
48+
noResultsText: { type: String, default: () => 'No results found' },
4749
defaultCountry: { type: String, default: () => 'us' },
4850
eagerValidate: { type: Boolean, default: () => true },
4951
useIcon: { type: Boolean, default: () => false },

0 commit comments

Comments
 (0)