This content originally appeared on Go Make Things and was authored by Go Make Things
Yesterday, we wrote a simple progressively enhanced autocomplete component using the datalist element and some vanilla JS. Today, I wanted to look at how to abstract it to work with multiple components and endpoints.
Let’s dig in!
(You should go read yesterday’s article first, if you haven’t already, or this one won’t make much sense.)
Updating the HTML
First, I don’t want to hard code the endpoint for my data into the JavaScript.
I’ll add a [data-autocomplete] attribute to my autocomplete field, and set the endpoint for its data as its value.
<label for="wizards">Who is the best wizard?</label>
<input type="text" id="wizards" data-autocomplete="https://gomakethings.com/demos/wizards.json">Updating the JavaScript
Instead of getting a specific field, I’ll use document.querySelectorAll() to get all fields with the [data-autocomplete] attribute.
// Get the autocomplete fields
let fields = document.querySelectorAll('[data-autocomplete]');
Then, I’ll loop through each field, fetch its data, and progressively enhanced it just like we did yesterday. I’ll need to also pass the field in to renderDatalist() as an argument.
// Loop through each field
for (let field of fields) {
// Get the endpoint
let endpoint = field.getAttribute('data-autocomplete');
// Fetch the data and render the datalist element
fetch(endpoint).then(function (response) {
if (response.ok) {
return response.json();
}
throw response;
}).then(function (data) {
renderDatalist(data, field);
}).catch(function (error) {
console.warn(error);
});
}
Inside the renderDatalist() method, we need to abstract a few more things.
First, we’ll use the field.id as part of the datalist.id value instead of just hard-coding it as wizards-data. We’ll also replace the wizards field variable with the field.
And in the for...of loop, we’ll change wizard to item.
/**
* Create and render the datalist element
* @param {Array} data The data to use for the list
* @param {Node} field The field to associate the datalist with
*/
function renderDatalist (data, field) {
// Create the datalist element
let datalist = document.createElement('datalist');
datalist.id = `${field.id}-data`;
field.setAttribute('list', datalist.id);
// Create fragment for option elements
let fragment = document.createDocumentFragment();
// Create list options
for (let item of data) {
let option = document.createElement('option');
option.textContent = item;
fragment.append(option);
}
// Add options to datalist
datalist.append(fragment);
// Inject into the DOM
field.after(datalist);
}
Now, we can add multiple elements to the page, and progressively enhance each into its own autocomplete component with its own endpoint.
This content originally appeared on Go Make Things and was authored by Go Make Things
Go Make Things | Sciencx (2021-05-07T14:30:00+00:00) Abstracting a vanilla JS autocomplete component. Retrieved from https://www.scien.cx/2021/05/07/abstracting-a-vanilla-js-autocomplete-component/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.