A small Vue.js app

Adding tags to an array

In the previous post, I gave my little Vue app the capability to take user input using an element with the attribute contenteditable="true".

Goal

I want to do a similar thing here, for adding tags.

Groundwork

Because I may want to add multiple tags, I need to declare an array, rather than a string, to store them in. This will be called tempTags:

data: {
  appTitle: 'Now we are adding tags to an array.',
  tempText: 'Texty text text. Semper ubi sub ubi',
  tempTags: ['onetag', 'twotag', 'threetag', 'four']
},

In the app’s template, I add an event listener, this time on the "newtag-tiddler" <div>:

<div id="newtag-tiddler" contenteditable="true" @blur="addNewTag"></div>

The @blur event handler will invoke the addNewTag(ev) method, which has to do a bit more than updateTempText(ev) did in the previous post:

Breakdown

  1. Instead of replacing the value of a data property with a new value, add the new tag to the array
  2. Remove the new tag again if it was a duplicate
  3. Clear the editable <div>, ready to receive another tag

1. Add the new tag to the tempTags array

Vue’s reactivity system doesn’t handle direct changes to items within an array by index, or direct changes to its length, but it does notice replacement of the whole array, as well as mutations by methods such as push().

addNewTag(ev) {
  this.tempTags.push(ev.target.textContent)
}

2. Remove duplicates from the array

It doesn’t make sense to store the same tag twice. Copy the unique tags from tempTags to a new array using ...new Set(), and replace tempTags with it.

addNewTag(ev) {
  this.tempTags.push(ev.target.textContent)
  var uniqueList = [...new Set(this.tempTags)]
  this.tempTags = uniqueList
}

As I understand it, in a simple method like this, it doesn’t matter whether I use let or var. Since the var is defined inside a function, its scope is limited to within the function; it’s not going to pollute the global scope. Using let could restrict the scope further if needed (if there were block statements within the function), but it’s not needed here. Kyle Simpson (video) gave some examples where unnecessary use of let over var can result in harder-to-debug code.

3. Clear the contents of the editable <div>, ready for a new tag

Set the newtag-tiddler element’s textContent property to an empty string to clear it once the tag has been added to the array in data.

addNewTag(ev) {
  this.tempTags.push(ev.target.textContent)
  var uniqueList = [...new Set(this.tempTags)]
  this.tempTags = uniqueList
  ev.target.textContent = ''
}

Demo

We no longer need to display the value of tempText, so I’ve removed that from the template to clean it up a bit, and added a simple kludge using mustache interpolation to show us the tempTags array. It literally displays an array, square brackets and all.

Now the text in the "newtag-tiddler" <div> is added as a tag when the <div> loses focus. If we try to add the same tag twice, the duplicate is immediately removed.

The Clear and Submit buttons still don’t do anything, although clicking one of them when "newtag-tiddler" has focus does cause it to lose focus, and therefore adds the text to the tag list.

In the next post, I’ll get the app to display the existing tags in a more useful and attractive way.