Datalists with Vue.js

Datalists with Vue.js

This isn't necessarily a very exciting post, but a few days back someone asked me about integrating Vue.js with datalist tags. The datalist tag is one of my favorite HTML tags and something I've blogged about a few times in the past. If you aren't familiar with it, it basically provides a "autosuggest" style experience to an input tag.

The HTML is pretty simple. Here is the example used in the MDN article I linked to above:

<label for="myBrowser">Choose a browser from this list:</label>
<input list="browsers" id="myBrowser" name="myBrowser" />
<datalist id="browsers">
  <option value="Chrome">
  <option value="Firefox">
  <option value="Internet Explorer">
  <option value="Opera">
  <option value="Safari">
  <option value="Microsoft Edge">
</datalist>

Basically - you create a <datalist> element and supply options. You then take your input and add the list="id of the list" attribute. Now when the user types, they will get suggestions based on the list and what they've typed in. It's pretty well supported (basically everyone but Safari and Mobile Safari, because of course) and fails gracefully (the user can still type anything they want). How would you combine this feature with Vue.js? Let's look at a static example. First, the HTML:

<div id="app">
  <input type="text" v-model="film" list="films">
  <datalist id="films">
    <option v-for="film in films">{{film}}</option>
  </datalist>
</div>

You can see the input field and the list. The option tag is tied to a variable called films. Now let's look at the JavaScript:

const app = new Vue({
  el:'#app',
  data() {
    return {
      film:'',
      films:[
        "A Throne Too Far",
        "The Cat Wasn't Invited",
        "You Only Meow Once",
        "Catless in Seattle"
	    ]
	}
  }
})

Not too exciting, but it works rather well. You can test it below:

See the Pen Static Datalist by Raymond Camden (@cfjedimaster) on CodePen.

How would you make it dynamic? Simple - just change how the data is generated. Here's an example of that:

const app = new Vue({
  el:'#app',
  data() {
    return {
      film:'',
      films:[]
    }
  },
  created() {
    fetch('https://swapi.dev/api/films/')
    .then(res => res.json())
    .then(res => {
      this.films = res.results.map(f => {
        return f.title;
      })
    })
  }
})

All I did was add in a created event handler and hit the Star Wars API for my data. You can test the result below:

See the Pen Dynamic Datalist by Raymond Camden (@cfjedimaster) on CodePen.

I may be biased - but everything is better in Vue.

Header photo by Ilya Pavlov on Unsplash

Archived Comments

Comment 1 by Antoine Moulin posted on 5/6/2018 at 10:49 PM

Hi. It's great. But how can you get the id of film ?
I tryed v-bind={id=film.id, nom=film.nom) in option but v-model of input don't catch bind of option

Comment 2 (In reply to #1) by Raymond Camden posted on 5/7/2018 at 2:15 PM

Unfortunately, datalists are tied to a text field which can only hold string information. You would want to use it in cases where you *know* the label (film title for ex) is 100% unique. You could then do a look up to get the ID.

Comment 3 by NM posted on 2/11/2019 at 7:56 PM

Thanks for making this tutorial. Unfortunately, it looks like we can't use hyperlinks in the datalist options? I wanted to not only show the data, but also make them clickable to their respect pages.

Comment 4 (In reply to #3) by Raymond Camden posted on 2/11/2019 at 8:02 PM

See the comment below - the values can only be strings and since the selected values go into an input box, you can't have rendered HTML there. I'd look for more of a Vue autocomplete type control.

Comment 5 by TuffTruth posted on 5/1/2019 at 6:53 PM

Didn't work for me. As soon as I bound the model to the input control, the autocomplete stopped working

Comment 6 (In reply to #5) by Raymond Camden posted on 5/1/2019 at 6:57 PM

Can you share the URL so I can try?

Comment 7 (In reply to #5) by exetico posted on 9/16/2020 at 6:27 AM
Comment 8 (In reply to #7) by Raymond Camden posted on 9/16/2020 at 12:58 PM

CodePen is updated. Blog post is updated but will need about 5 more minutes before live. Thanks.