Hi, this is something I’ve always wanted to implement but couldn’t quite work out how.
Say I want to use an AutocompleteInput
widget but I want the options to be fetched dynamically from a search of that input.
E.g. the user inputs “hello” and I have an API endpoint that I can call with this string that will return a list of potential matches. I.e. an external search method.
I wondered about subclassing the widget and adding a depends on the value_input
e.g.
class FetchAutocomplete(pn.widgets.AutocompleteInput):
"""Widget to autocomplete by fetching options."""
@pn.cache(ttl=3600, max_items=25)
async def _fetch_options(self, value: str) -> list[str]:
"""Fetch the options for the widget."""
try:
async with MyClient() as client:
response: dict = await client.find(value)
except httpx.HTTPError as error:
return []
return [result["name"] for result in response["results"]]
@param.depends("value_input", watch=True)
async def _update_options(self):
"""Update the options for the widget."""
if len(self.value_input) < self.min_characters:
return
self.options = await self._fetch_options(self.value_input)
Now this somewhat works but the problem is that this is not in sync with the user input. As soon as the input is entered it does the search against the current options. The options are updated they are not refreshed on the input. Enter one more character and then it will present the options that match from the previous search.
This makes sense to me as to what’s going on, but I can’t quite work out how to trigger a refresh of the matches after the options have been updated, if it is even possible?
Of course there might be a better way to do this completely?
Thanks for any help with this.