vue-tagsinput
vue-tagsinput copied to clipboard
Tag input drops down in all of the components it is used
Hi, I'm using this input in many of my components and I have noticed that after running axios request to save data, all of the inputs get expanded (shown in the gif). I have also noticed that this started happening after I added the "typeahead-activation-threshold="0" " prop, if I remove it, this issue doesn't happen. Perhaps someone has faced a similar issue or might have some insight on what might be causing this and how to fix it? Is there a way to manually trigger dropdown?
Here's my custom component using tags input
<template>
<div>
<tags-input element-id="tags"
v-model="selectedTags"
:existing-tags="availableTags"
:before-adding-tag="checkIfExists"
:delete-on-backspace="false"
:typeahead-activation-threshold="0"
typeahead-style="dropdown"
placeholder="Tags"
@tag-removed="remove"
@tag-added="add"
:typeahead="true" v-if="!loading"></tags-input>
</div>
</template>
<script>
import Tag from '../Models/Tag'
export default {
watch: {
selectedTags: function(newValue, oldValue){
this.$emit('input', this.selectedTags);
},
inputtags: {
handler: function(newValue, oldValue) {
if(!_.isEqual(oldValue, newValue)){
this.selectedTags = newValue;
}
},
deep: true,
immediate: true
}
},
computed: {
tags(){
return Tag.query().orderBy('value').get();
},
availableTags(){
return this.tags.map(function(a){
return {key: a.key, value: a.value};
});
}
},
props: [
'inputtags'
],
data(){
return {
tagLabel: 'tags',
tagInput: '',
selectedTags: [],
loading: true,
}
},
mounted(){
this.fetchTags();
},
methods:{
fetchTags(){
//checking if tags have not yet been loaded
if(!Tag.exists()){
var promises = [];
promises.push(Tag.api().fetch());
var self = this;
Promise.all(promises).then(function (res) {
self.loading = false;
});
}else{
this.loading = false;
}
},
checkIfExists(item){
if(!item.key){
if(confirm(window.translate('dictionary.addNewTag'))){
axios.post('/api/tags/create', {tagname: item.value})
.then(response => {
var respTag = response.data.data;
Tag.insert({
data: respTag
});
this.selectedTags.push(respTag);
this.add(respTag);
});
}
return false;
}else{
return true;
}
},
remove(slug){
this.$emit('remove', slug)
},
add(slug){
this.$emit('add', slug)
}
}
}
</script>
<style lang="scss">
.typeahead-dropdown{
max-height:16rem;
overflow: auto;
}
</style>
Found a hack-ish way to solve this. That's by controlling typeahead-activation-threshold with a variable and changing this variable on @focus and @blur events. Here's my working example of the fix
<template>
<div>
<tags-input element-id="tags"
v-model="selectedTags"
@focus="threshold = 0"
@blur="threshold = 1"
:existing-tags="availableTags"
:before-adding-tag="checkIfExists"
:delete-on-backspace="false"
:typeahead-activation-threshold="threshold"
:typeahead-show-on-focus="true"
:typeahead-hide-discard="true"
typeahead-style="dropdown"
placeholder="Tags"
@tag-removed="remove"
@tag-added="add"
:typeahead="true" v-if="!loading"></tags-input>
</div>
</template>
...
data(){
return {
...
threshold: 1,
}
},
...
Yep, also happening to me. If the threshold is 0, once the tags are loaded the typeahead dropdown pops up uncalled. As a solution I've set the threshold to 1, but it is not ideal.