Open jAlfredsson opened 5 years ago
Update: it seems as clicking the dropdown fires both the @open and @close-event right after another.. Is this expected behaviour? I'm kind of new to Vue, currently trying to find some pretty "hacky" way to stop the event chain once the @open is fired, but it doesn't feel as that should be the right way to do it..
@jAlfredsson, It sounds really strange! Are there any ways I can reproduce the issue?
@iamstevendao I will see if I can cook something up .. however I just recognized I'm registering the vue-tel-input in my component rather than the global Vue instance, as I'd prefer doing it.. I'm a bit new to Vue, when I tried set it up in a JSFiddle it works as expected..
My awful hack to make it work looks like this:
private onDropdownOpen(){
this.showDropdown = !this.showDropdown;
}
private onDropdownClose(){
const el = this.$children[0].$refs.list as HTMLElement;
this.$nextTick(() => {
el.style.display = (this.showDropdown ? 'block' : 'none')
})
}
Here's my complete "BaseFormTelInput.vue" component:
<template>
<label class="base-form-input">
<span class="base-form-input__label">
{{ label }}
<span v-if="optional" class="base-form-input__flag">* optional</span>
</span>
<ul class="base-form-input__errors" v-if="errors.length > 0">
<li class="error" v-for="(error, index) in errors" :key="index">{{ error }}</li>
</ul>
<vue-tel-input
:value="value"
v-bind="$attrs"
:defaultCountry="defaultCountry"
:disabledFetchingCountry="!!defaultCountry"
wrapperClasses="telinput"
inputClasses="input_field"
dynamicPlaceholder
@input="phoneCheck"
@validate="$emit('validityChange', $event)"
@open="onDropdownOpen"
@close="onDropdownClose"
/>
</label>
</template>
<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';
import { VueTelInput, VueTelInputResponse } from 'vue-tel-input';
@Component({ components: { VueTelInput } })
export default class BaseFormTelInput extends Vue {
@Prop({ required: true })
public label!: string;
@Prop({ type: Boolean, default: false })
public optional!: boolean;
@Prop({ type: Array, default: () => [] })
public errors!: string[];
@Prop()
public value?: any;
@Prop()
public defaultCountry?: string;
showDropdown = false;
private onDropdownOpen(){
this.showDropdown = !this.showDropdown;
}
private onDropdownClose(){
const el = this.$children[0].$refs.list as HTMLElement;
this.$nextTick(() => {
el.style.display = (this.showDropdown ? 'block' : 'none')
})
}
private phoneCheck(num: string, obj: VueTelInputResponse) {
this.$emit('input', obj);
if (!num.length) {
this.$emit('validityChange', { isValid: true });
}
}
}
</script>
<style lang="scss" scoped>
.base-form-input {
margin: 8px 0;
transition: 0.1s;
&:hover {
color: $color-theme-yellow;
}
&__label {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
&__flag {
font-size: 18px;
color: black !important;
}
&__errors {
font-size: 16px;
color: $color-theme-red;
.error {
margin: 4px 0;
}
}
.telinput {
padding: 6px 8px;
margin-top: 4px;
font-size: 20px;
width: 100%;
background: $color-input;
border: 2px solid black;
}
/deep/ .input_field {
background: $color-input;
font-size: 20px;
width: 100%;
}
}
</style>
I will see if I can reproduce in a fiddle... but there's gotta be something I'm just doing wrong.
I had the same issue. This happens when it is wrapped with a parent <label>
element.
Same problem when the input
is wrapped in a label
.
Here is my hacky workaround:
<template>
<vue-tel-input
:class="{ 'vti_hack': vti_hack > 0 }"
@open="!vti_hack && (vti_hack = 2)"
@close="vti_hack -= 1"
/>
</template>
<script>
data() {
return {
vti_hack: 0,
}
}
</script>
<style scoped>
.vti_hack::v-deep .vti__dropdown-list {
display: block !important;
}
</style>
@iamstevendao Is there a planned fix for this?
Edit: I've noticed that if dropdownOptions.showSearchBox is set to true then the drop down works 🤔
I can't get the drop down to show for some reason.. it keeps its
style="display:none"
when clicking..I wrapped it in a component - parent:
<base-form-tel-input :label="at('form.shipping.labelPhone')" type="tel" :value="address && address.phone" :defaultCountry="address && address.country && address.country.id" @input="addressForm.phone = $event.number.e164" @validityChange="validPhone = $event.isValid" :errors="!validPhone ? addressForm.getErrorMessagesForProperty('phone') : []" optional />
and the base-form-tel-input:
<vue-tel-input :value="value" v-bind="$attrs" :defaultCountry="defaultCountry" disabledFetchingCountry wrapperClasses="telinput" inputClasses="input_field" dynamicPlaceholder @input="phoneCheck" @validate="$emit('validityChange', $event)" />
and the css for the classes i'm sending: `.telinput { padding: 6px 8px; margin-top: 4px; font-size: 20px; width: 100%; background: $color-input; border: 2px solid black; }
/deep/ .input_field { background: $color-input; font-size: 20px; width: 100%; }`
What am I missing?