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
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
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.
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.
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.
Didn't work for me. As soon as I bound the model to the input control, the autocomplete stopped working
Can you share the URL so I can try?
Use https://swapi.dev/api/films/ instead.
CodePen is updated. Blog post is updated but will need about 5 more minutes before live. Thanks.