autoComplete.js
autoComplete.js copied to clipboard
Make current element available in src callback
Is your feature request related to a problem? Please describe. I'm creating multiple autocomplete elements on the page dynamically. They receive suggestions from a JSON endpoint which is resolved at template rendering time. To pass the proper endpoint to the autocomplete input, I would like to do the following:
<input type="text" class="autocomplete" data-suggestions-endpoint="{{ route('foo.bar') }}">
In the next step, I would configure AutoComplete:
const autoCompleteJS = new autoComplete( {
selector: '[data-suggestions-endpoint]',
data: {
src: query => fetch( url ).then(r => r.json())
}
} );
Alas, there's no way to get access to the data property.
Thoroughly Describe the solution you'd like It would be great if the current element were passed to the query callback as the second parameter:
const autoCompleteJS = new autoComplete( {
selector: '[data-suggestions-endpoint]',
data: {
src: (query, element) => fetch( element.dataset.suggestionsEndpoint )
.then(r => r.json())
}
} );
Please provide a few use cases for this feature
- Configuring dynamic endpoints, as above
- Bridging between server-side rendered templates, and frontend applications - that way, autocomplete could be configured using declarative attributes on the input instead of inline JS
- Checking the current state of the input element; you might want to abort searching if the user leaves the input field (I'll admit this one is a little convoluted)
Please Describe alternatives you've considered Obviously, binding every element by itself:
const instances = Array.from( document.querySelectorAll(
'[data-suggestions-endpoint]'
) ).map(element => new autoComplete( {
selector: () => element,
data: {
src: (query) => fetch( element.dataset.suggestionsEndpoint )
.then(r => r.json())
}
} ) );
This works, but has the drawback of creating several instances instead of a single one.
Additional context
@TarekRaafat What do you think about this issue? If this is something we want for the project I would gladly provide a PR for that. I definitely see the use case and I also had a case like this already where this feature would have been useful.
+1
I tried the alternative @Radiergummi (thanks for that!) proposed, but could not get it to work.
Uncaught (in promise) TypeError: element is undefined
in line
src: (query, element) => fetch( element.dataset.suggestionsEndpoint )
I tried the alternative @Radiergummi (thanks for that!) proposed, but could not get it to work.
Uncaught (in promise) TypeError: element is undefined
Sorry, that was copy pasted sloppily! If you remove the second parameter element
from the callback, it will use the instance from the parent scope, and work.