autoComplete.js
autoComplete.js copied to clipboard
Suppress searchEngine with async data function is exhaustive
Is your feature request related to a problem? Please describe.
When I have a src: async ...
that makes a request to my backend, my backend will provide search results that are exhaustive. By exhaustive, I mean that they by definition should show in the results list, even though they may not contain a substring of the query string. Sometimes, the search results look nothing like the query string.
Because those search results look nothing like the query string, the searchEngine
will reject it as a candidate, which means it doesn't show up in the results.
Thoroughly Describe the solution you'd like
I think the most conclusive way to answer this is that the backend should be able to also give the highlighted parts to return, and then the searchEngine is suppressed.
For example, let's say I search for "Mesa, AZ". The backend returns "Mesa, Arizona" and it also indicates that the highlighted substring is "Mesa, " (it shouldn't be as integer offsets, because then there's an ambiguity if it's unicode codepoints, bytes, etc).
A clear and concise description of what you want to happen.
Please provide a few use cases for this feature
- Let the backend be canonical
- Search for things that don't actually match by string, for example, you search for "Elevator" and you get "Lift"
Please Describe alternatives you've considered
Make searchEngine just return the shortest length string, but that would look kinda weird and I don't really understand the searchEngine
API as documented well enough.
It's kind of hard to parse what you want to accomplish, but I'm 90% certain that it's entirely possible already.
.searchEngine
can be set to your own function, the signature is (query: string, record: any)
, so for example:
new autoComplete({
searchEngine: (q, r) => return r.propertythatcontainsmatchingtext,
})
Whatever you return from the search engine is what will be displayed in the dropdown by default. You can of course change this with the resultItem.element
setting, etc.
searchEngine
is invoked either (a) once per result returned from data.src
if data.keys
is not set, or (b) once per key per result if data.keys
is set.
The record
argument is either (a) each array index returned from data.src
if data.keys
is not set, or (b) data.src[...][key]
for each data.keys
entry.
Returning null
or false
or undefined
from searchEngine
makes autoComplete.js ignore that data entry.
Hi, I am facing the same issue right now. And I also would like to have the results highlighted. With the solution above, matching results are not highlighted at all.
I came up with this solution :
searchEngine: (query, record) => record.includes(query)
? autoComplete.search(query, record, { highlight: true})
: record
I have a similiar situation. In 'data.src' I am requesting an API which performs a full text search in documents, the result of a search is the list of document names containing the searched keyword. What works for me is overwriting the search engine and directly returning the found record(s):
searchEngine: (query, record) => {
return record
}
I propose this solution.
It works well for me with multiple keywords and the highlight feature. I wrap with outside my loop to avoid problems if I have a string with 'mark' in my keywords.
searchEngine: function (query, record){
query.replace(/\s+/g,' ').trim().split(" ").forEach(function (substring){
var regex1 = RegExp(substring, "i")
if(regex1.test(record)){
record = record.replace(regex1 ,'!*$&*!');
}
})
return record.replaceAll("!*", "<mark>").replaceAll("*!", "</mark>")
}
To display all records returned by my API yet highlighting those that do contain the query, I used:
searchEngine: (query, record) => autoComplete.search(query, record, { highlight: true }) || record