Tagging system with auto complete using vue.js

This module allows the user to type multiple items as tags or select tags from a suggestion list as they type.

Project files:

  • tags.vue
  • tags.js
  • tags.css

1. Tags form

tags.vue
  <div><span>tags:</span>

  <div class="tags-input">
    <span v-for="(tag,index) in tags" :key="index">
      <span class="tag label label-info">/{/{ tag /}/}
        <a class="tags-input-remove" v-on:click="removeTag(index)">×</a></span>

    </span>
    <div style="display:inline-block; position:relative" >
      <input v-model="addedTag"  class="tags-input-text"
       placeholder="Add tag..." v-on:keyup.enter="inputEventHandlers"
       @input = 'change'
       @keydown.down = 'down'
       @keydown.up = 'up' />
     <ul class="dropdown-menu" v-bind:class="{'show':openSuggestion}">
        <li style="color:#6B6B6B" v-for="(suggTag,i) in matches" :key="i"  @click="suggestionClick(i)"
         v-bind:class="{'active': isActive(i)}">
          /{/{ suggTag['name'] /}/} </li>
        
      </ul>
    </div>

  </div>

</div>
							

While typing the tag a list of suggested tags will open allowing to choose pre-selected one or adding a new one. This template is formed of array of added tags represented as small clouds, an input fiels allowing user to type tag and a dropdown menu to show suggested tags.

2. Create javascript file

tags.js
 export default {
  name: 'tags',
  data() {
    return {
      addedTag: '',
      suggTags: [],
      current:null,
      open:false,
      tags:[]
    }
  },
  created() {
      //get result tags from database
      if (result) {
        this.suggTags = result;

      }


  },
  computed:{
    openSuggestion() {
       return this.addedTag !== "" &&
              this.matches.length != 0 &&
              this.open === true;
   },
   matches() {

       return this.suggTags.filter((str) => {

           return str['name'].indexOf(this.addedTag) >= 0;
       });
   }
 }

}
                           

On created function retieve top tags array from database. openSuggestion will check if input match any suggestion tag to open list. matches function filter that shows only matching tags.

  1. addedTag: input typed by user in the tag field.
  2. suggTags: retrieved object array like [“suggtag1″,”suggtag2″,”suggtag3”]
  3. tags: list of added tags.

3. Add methods

tags.js
methods: {

 suggestionClick(index) {
      if(this.tags.length<10){
        this.addedTag = this.matches[index].name;
        this.tags.push(this.addedTag);
        this.open = false;
        this.current=null;
        this.addedTag = '';
      }
    },
    complete(i) {
      this.addedTag = this.suggTags[i].name;
    },
    removeTag(i) {
      this.tags.splice(i, 1);

    },
    inputEventHandlers() {
      if (this.current !=null && this.tags.length<10){
        this.addedTag = this.matches[this.current].name;
        this.tags.push(this.addedTag);
      }else{
        if(this.addedTag != '' && this.tags.length<10){
      this.tags.push(this.addedTag);
    }
    }
    this.current=null;
      this.addedTag = '';
      this.open=false;
    },
    isActive(index) {
        return index === this.current;
    },
    change() {
      this.current = null;
      if (this.open == false) {
       this.open = true;

     }
       },
  up() { //When up pressed while suggestions are open
       if(this.current > 0)
           this.current--;
   },

  
   down() {
     if(this.current==null){this.current=0}
     else {if(this.current < this.matches.length - 1)
           this.current++;
         }
   },


  },
  
  

4. Styling our module

Let’s apply some CSS to make things look a bit nicer by adding the following

tags.css
.tags{padding-left:10px}
.tags span{float:left; margin-right:10px}
.tagcloud {
    margin-top: 10px;
}
.tag .tags-input-remove {
    margin-left:5px;
    color: #aaa;
    cursor:pointer;
    font-size:16px;
}

.tagcloud a ,.tags-input .tag{
    padding: 6px 7px;
    margin-right: 10px;
    line-height: 100%;
    display: inline-block;
    color: #FFF !important;
    background-color: #DADADA;
    border-radius: 3px;
    -webkit-border-radius: 3px;
    font-size: 12px !important;
}
.tag {

    font-weight: bold;
    margin-right: 5px !important;
}

.tagcloud a:hover {
    background-color: #42b883;
    border-color: #42b883;
}

                            

Done!!

Comments