How to create tags input component in vue.js

How to create tags input component in vue.js

Creating vue.js components has always been fun and easy for me. In this article, I will show you how you can create input for tags easily and simply, and not to forget to keep things clean and minimal.

To get started we need some prerequisites to be installed.

  1. Bootstrap
  2. Vue.js
  3. fontawesome

Goal

Our goal is to

  1. Have text input, where the user types text for a tag.
  2. Have an event where user presses enter, the text will be pushed into tags array.
  3. Show added a tag in the collection below text input.
  4. Have a remove button on each tag.

Process

So let's start with new vue.js component "TagsInput.vue".

<template>

</template>
<script>
export default {
  name: 'tags-input',
 }
</script>
<style scoped></style>

First, we will imagine how our tag will look like. I believe in a minimal design with the least markup. So we will take leverage of badge and badge-dark class provided in bootstrap to make our tag small and have a dark background.


Tag Example


<span class="badge badge-dark">
  Tag
  <i class="fa fa-times"></i>
</span>

We will now have to create text input along with label. Below we need a container to display all the added tags. Its better to wrap everything in a form group class to make things more clean.

<div class="form-group">
  <label for="txtTags">Tags</label>
  <input type="text" class="form-control" name="" id="txtTags" placeholder="Type and press enter">
  <div class="tagCollection mt-2">
    <span class="badge badge-dark ml-1">
      Tag
      <i class="fa fa-times"></i>
    </span>
  </div>
</div>

and add style for tagCollection class

<style scoped>
  .tagCollection{
    width: 100%;
    min-height: 200px;
    border: 1px #696969 dashed;
  }
</style>

Now that our controls are in place, its time to get in to real stuff and declare an array of tags and text input value.

data(){
  return{
    textValue: '',
    tags: [],
  }
},

Time to apply variables in their proper places. We can simply bind textValue variable to our text input using v-model. And we need to display all the items in tags array so using v-for to render the span multiple times.

<div class="form-group">
  <label for="txtTags">Tags</label>
  <input v-model="textValue" type="text" class="form-control" name="" id="txtTags" placeholder="Type and press enter">
  <div class="tagCollection mt-2">
    <span v-for="tag in tags" :key="tag + Math.random()" class="badge badge-dark ml-1">
      {tag}
      <i class="fa fa-times"></i>
    </span>
  </div>
</div>

We will create method to push text value into array upon pressing enter. Before doing so we will make sure that duplicates are avoided.

addTag(event){
  //Prevent default action of click event
  event.preventDefault()
  //Check if textbox value already exists, avoiding duplicates
  if(this.tags.indexOf(this.textValue) === -1){
    //Push value in array
    this.tags.push(this.textValue)
  }
  //clear textbox value
  this.textValue = ''
},

Another method for removing tag from array

removeTag(tag){
  this.tags.splice(this.tags.indexOf(tag), 1)
}

Finally, joining all bits and pieces together, we can end up with a simple looking and functional component.

<template>
    <div class="form-group">
        <label for="txtTags">Tags</label>
        <input v-model="textValue" v-on:keydown.enter="addTag" type="text" class="form-control" name="" id="txtTags" placeholder="Type and press enter">
        <div class="tagCollection mt-2">
            <span v-for="tag in tags" :key="tag + Math.random()" class="badge badge-dark ml-1">
                {tag}
                <i class="fa fa-times" v-on:click="removeTag(tag)"></i>
            </span>
        </div>
    </div>
</template>

<script>

export default {
    name'tag-input',
    data(){
        return{
            textValue'',
            tags: [],
        }
    },
    methods:{
        addTag(event){
            event.preventDefault()
            if(this.tags.indexOf(this.textValue) === -1){
                this.tags.push(this.textValue)
            }
            this.textValue = ''
        },
        removeTag(tag){
            this.tags.splice(this.tags.indexOf(tag), 1)
        }
    }
}
</script>

<style scoped>
      .tagCollection{
          width100%;
          min-height200px;
          border1px #696969 dashed;
      }
</style>

You can add more functionalities and features to it, for example: capitalize text input value before pushing into tags array. Or adding a hidden input element to hold string array in case you are posting data using the form. The sky is the limit.

Tags :
Share :
About Author
Jaswinder Singh Narula

Jaswinder Singh Narula

Vmware SME by day and hard core coder by night. Bringing perfection is my passion.

Leave a Comment

Comments
No comments yet.