Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppress searchEngine with async data function is exhaustive #284

Open
njaard opened this issue Sep 21, 2021 · 6 comments
Open

Suppress searchEngine with async data function is exhaustive #284

njaard opened this issue Sep 21, 2021 · 6 comments
Labels
enhancement New feature or request

Comments

@njaard
Copy link

njaard commented Sep 21, 2021

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

  1. Let the backend be canonical
  2. 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.

@njaard njaard added the enhancement New feature or request label Sep 21, 2021
@folknor
Copy link

folknor commented Sep 21, 2021

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.

@maevag
Copy link

maevag commented Feb 25, 2022

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.

@maevag
Copy link

maevag commented Feb 25, 2022

I came up with this solution :

searchEngine: (query, record) =>  record.includes(query)
          ? autoComplete.search(query, record, { highlight: true})
          : record

@StephanU
Copy link

StephanU commented Sep 1, 2022

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
}

@jules-w2
Copy link

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>")
}

@echolet
Copy link

echolet commented Feb 5, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants