stimulus-autocomplete
stimulus-autocomplete copied to clipboard
Suggestion: Allow to use local HTML instead of fetching from the server
Hi! First of all, thank you for your work on this!
If we allow using HTML data attributes with data in JSON format instead of fetching from the server, this will allow caching where the data is static while preventing more network requests.
Imagine the case of a country list, where it's a fixed list; we may want just to iterate and render the li
elements, but currently, we cannot use the autocomplete.
Do you think this could be a nice addition to this lib?
I just tried abusing a data URL for this:
<div data-controller="autocomplete" data-autocomplete-url-value="data:text/html,%3Cli%20class%3D%22list-group-item%22%20role%3D%22option%22%20data-autocomplete-value%3D%221%22%3EBlackbird%3C%2Fli%3E%0A%3Cli%20class%3D%22list-group-item%22%20role%3D%22option%22%20data-autocomplete-value%3D%222%22%3EBluebird%3C%2Fli%3E%0A%3Cli%20class%3D%22list-group-item%22%20role%3D%22option%22%20data-autocomplete-value%3D%223%22%3EMockingbird%3C%2Fli%3E%0A">
<input name="birds" type="text" class="form-control" data-autocomplete-target="input" placeholder="search a bird" autofocus/>
<input type="hidden" name="bird_id" data-autocomplete-target="hidden"/>
<ul data-autocomplete-target="results" class="list-group"></ul>
</div>
It works partially 🤣 The query parameters obviously become part of the answer.
https://user-images.githubusercontent.com/245443/191965163-8efcc89e-3aeb-4fcd-85e1-becdcb511e6a.mp4
@fidalgo if you just want to solve this issue for a particular feature you could override doFetch
in the controller to return an HTML with the options you want to show.
<div data-controller="combobox" data-combobox-options-value="[JSON array with options]">
...
</div>
class Combobox extends Autocomplete {
static values = { options: Array }
doFetch = async () => {
const query = this.inputTarget.value.trim().toLowerCase()
const matchingOptions = this.optionsValue.filter(o => o.toLowerCase.includes(query))
return matchingOptions.map(o => `<li data-autocomplete-value="${o}">${o}</li>`).join("\n")
}
}
If however you wan to add the feature to the library, I'd suggest going in the opposite direction: create a base Combobox
class that allows filtering a set of static options and then define Autocomplete
as a subclass of Combobox
, adding the methods to fetch new options from the server in Autocomplete
.
I'd be happy to accept patches implementing that, although it seems a substantial change.
+1