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

Ability to filter suggestions before display #251

Closed
cdtinney opened this issue Sep 19, 2018 · 13 comments
Closed

Ability to filter suggestions before display #251

cdtinney opened this issue Sep 19, 2018 · 13 comments

Comments

@cdtinney
Copy link
Contributor

cdtinney commented Sep 19, 2018

Do you want to request a feature or report a bug?

Feature.

What is the current behavior?

  • Suggestions are retrieved via querying dataset sources
  • Suggestions are cached so that subsequent identical queries do not query the dataset source
  • Suggestions are not filtered before displaying

What is the expected behavior?

  • Suggestions can be filtered both after a query or cache hit, before they are displayed

Use Case

I am using the autocomplete input to allow the user to add "tags" to a list. If the user adds a tag, it needs to be hidden from the dropdown subsequently (i.e. the tag can only be added once).

Workarounds I've Tried

  • Using a template for suggestion that returns an empty element. This doesn't work when there are no suggestions as the empty template doesn't get rendered.
  • Filtering results after the dataset source is queried. This works for all cases except cache hits.

Alternatives

One alternative would be to allow developers to override caching behaviour.

@Haroenv
Copy link
Contributor

Haroenv commented Sep 19, 2018

The second argument to the hits function accepts any search parameter, and thus allows you to filter. All filtering options are available here: https://www.algolia.com/doc/api-reference/search-api-parameters/

@cdtinney
Copy link
Contributor Author

@Haroenv I'm not using an Algolia source. Would that be called even if suggestions were cached, though?

@Haroenv
Copy link
Contributor

Haroenv commented Sep 19, 2018

Autocomplete doesn't have a cache, can you give the code you're using?

@cdtinney
Copy link
Contributor Author

Using jQuery JS for v0.31.0.

This looks like caching to me: https://github.com/algolia/autocomplete.js/blob/v0.31.0/dist/autocomplete.jquery.js#L2537

@Haroenv
Copy link
Contributor

Haroenv commented Sep 19, 2018

I didn't know that, I've only worked on other parts of the code base. Do you have a suggestion on how to fix it, maybe allow disabling of the cache?

The best way would be that you allow filtering (maybe with a callback argument) to your own source, that way you can control filtering without a change in cache etc.

@cdtinney
Copy link
Contributor Author

I think filtering is the best approach as disabling cache requires more work for the developers (disable cache + handle filtering of results).

A new option called filter could be added to dataset objects. This should be a function.

It could be implemented inside the handleSuggestions function inside update:

function handleSuggestions(suggestions) {  
  // if the update has been canceled or if the query has changed
  // do not render the suggestions as they've become outdated
  if (this.canceled || query !== this.query) {
    return;
  }

  // Apply filters
  var filteredSuggestions = this._applyFilters(suggestions);

  // concat all the other arguments that could have been passed
  // to the render function, and forward them to _render
  var extraArgs = [].slice.call(arguments, 1);
  this.cacheSuggestions(query, filteredSuggestions, extraArgs);
  this._render.apply(this, [query, filteredSuggestions].concat(extraArgs));
}

Thoughts?

@Haroenv
Copy link
Contributor

Haroenv commented Sep 19, 2018

Is there a reason you prefer this in the library over putting it in userspace (like the Algolia one does)

@cdtinney
Copy link
Contributor Author

cdtinney commented Sep 19, 2018

I'm not sure how to implement it in userspace to bypass the caching since the source function won't be called at all. I could add query parameters to do the filtering server side, yes, but that requires source to be called.

Suggestions are welcome.

@cdtinney
Copy link
Contributor Author

cdtinney commented Sep 19, 2018

I have this implemented locally. Would you be open to a PR (with tests, docs, etc.)?

@Haroenv
Copy link
Contributor

Haroenv commented Sep 20, 2018

Would be interesting to see what you came up with yes 😊

I've taken a deeper look and noticed that the cache in autocomplete.js is only for a single previous query. In the case of filtering frontend, it should be fairly safe to simply disabling the cache, but I think it will make more sense when I see what your implementation is

@cdtinney
Copy link
Contributor Author

It turns out that filtering is not sufficient. There is an edge case that it doesn't handle:

  • Enter query X
  • Source returns results A, B, C
  • A is deleted from the server by aother user
  • Enter query X again
  • Source returns same results

Disabling caching is a better approach. It still leaves caching possible in userspace. I will work on a MR.

@Haroenv
Copy link
Contributor

Haroenv commented Sep 21, 2018

Thanks, that's what I thought would be more appropriate too! a PR would be appreciated 🚀

@cdtinney
Copy link
Contributor Author

Closing. There is another solution that doesn't require lib changes: passing the filter function to the dataset on initialization.

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

No branches or pull requests

2 participants