























HTML’s datalist element provides native autocomplete functionality, but it’s entirely static—you have to know all the options up front. The dynamic-datalist web component solves this by fetching suggestions from an API endpoint as users type, giving you the benefits of native autocomplete with the flexibility of dynamic data.
This component is a modern replacement for my old jQuery predictive typing plugin. I’ve reimagined it as a standards-based web component.
To use the component, wrap it around your input field and specify an endpoint:
<dynamic-datalist endpoint="/api/search">
<label for="search"
>Search
<input
type="text"
id="search"
name="search"
placeholder="Type to search..."
/>
</label>
</dynamic-datalist>
As users type, the component makes GET requests to that endpoint, passing in the typed value as the “query” parameter (e.g., /api/search?query=WHAT_THE_USER_TYPED). The response from the endpoint is used to populates a dynamic datalist element with the results.
The structure of the response should be JSON with an options array of string values:
{
"options": ["option 1", "option 2", "option 3"]
}
Under the hood, the component:
datalist element for your input,input,datalist option elements, andAll of this happens transparently—users just see autocomplete suggestions appearing as they type.
You can change the submission method via the method attribute:
<dynamic-datalist endpoint="/api/lookup" method="post">
<label for="lookup"
>Lookup
<input type="text" id="lookup" name="lookup" />
</label>
</dynamic-datalist>
This sends a POST request with a JSON body: { "query": "..." }. Currently GET and POST are supported, but I could add more if folks want them.
As I mentioned, the component uses “query” as the parameter name by default, but you can easily change it via the key attribute:
<dynamic-datalist endpoint="/api/terms" key="term">
<label for="search"
>Term search
<input type="text" id="search" name="term" />
</label>
</dynamic-datalist>
This sends the GET request /api/terms?term=....
If your input already has a datalist defined, the component will inherit it and replace the existing options with the fetched results, which makes for a nice progressive enhancement:
<dynamic-datalist endpoint="/api/cities">
<label for="city"
>City
<input
type="text"
id="city"
list="cities-list"
placeholder="Type a city…"
/>
</label>
<datalist id="cities-list">
<option>New York</option>
<option>Los Angeles</option>
<option>Chicago</option>
</datalist>
</dynamic-datalist>
Users see the pre-populated cities immediately, and as they type, API results supplement the list. If JavaScript fails or the web component doesn’t load, users still get the static options. Nothing breaks.
If you want to tap into the component’s event system, it fires three custom events:
dynamic-datalist:ready - Fired when the component initializesdynamic-datalist:update - Fired when the datalist is updated with new optionsdynamic-datalist:error - Fired when an error occurs fetching dataconst element = document.querySelector("dynamic-datalist");
element.addEventListener("dynamic-datalist:ready", (e) => {
console.log("Component ready:", e.detail);
});
element.addEventListener("dynamic-datalist:update", (e) => {
console.log("Options updated:", e.detail.options);
});
element.addEventListener("dynamic-datalist:error", (e) => {
console.error("Error:", e.detail.error);
});
Each event provides helpful detail objects with references to the input, datalist, and other relevant data.
Check out the demo for live examples (there are also unpkg and ESM builds if you want to test CDN delivery):
The project is available on GitHub. You can also install via npm:
npm install @aarongustafson/dynamic-datalist
If you go that route, there are a few ways to register the element depending on your build setup:
import { DynamicDatalistElement } from "@aarongustafson/dynamic-datalist";
customElements.define("dynamic-datalist", DynamicDatalistElement);
import "@aarongustafson/dynamic-datalist/define.js";
// or, when you need to wait:
import { defineDynamicDatalist } from "@aarongustafson/dynamic-datalist/define.js";
defineDynamicDatalist();
<script> tag<script
src="./node_modules/@aarongustafson/dynamic-datalist/define.js"
type="module"
></script>
Regardless of how you register it, there are no framework dependencies—just clean autocomplete powered by your API. As I mentioned, it’s also available via CDNs, such as unpkg too, if you’d prefer to go that route.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。