awesomplete icon indicating copy to clipboard operation
awesomplete copied to clipboard

async item loading

Open calvinmetcalf opened this issue 9 years ago • 14 comments

The times I need autocomplete (as opposed to a select) are when I have huge amounts of data in a database (either remote or in browser), the ability to specify an async function would go a long way towards making this useful.

calvinmetcalf avatar Feb 20 '15 13:02 calvinmetcalf

Awesome idea!

Area51Brett avatar Feb 20 '15 16:02 Area51Brett

How do you picture this working? What's your dream API for it?

LeaVerou avatar Feb 21 '15 06:02 LeaVerou

Calls a function with what has been written, and passes result to Promise.resolve which should resolve to be an array of whatever the needed values are.

On Sat, Feb 21, 2015, 1:46 AM Lea Verou [email protected] wrote:

How do you picture this working? What's your dream API for it?

— Reply to this email directly or view it on GitHub https://github.com/LeaVerou/awesomplete/issues/15#issuecomment-75359211.

calvinmetcalf avatar Feb 21 '15 15:02 calvinmetcalf

I think most of this can already be accomplished since Awesomplete can change its list property to update the items. Example:

// page load
var input = document.getElementById('listOfLotsOfItems');
var awesome = new Awesomplete(input);
// at some point do an ajax call to search for items or something, possibly using the data already filled in the input field
$.ajax(
  // update the list of items when response arrives
  success : function(data) { awesome.list=data; }
);

Maybe all that's needed is to ensure that the Awesomplete form actively updates as the list is updated, in the even that ajax requests are made as the user types. Ex: user starts typing, ajax request is made to lookup data based on current value, suggestions come back, list is updated.

neandrake avatar Feb 21 '15 20:02 neandrake

Yup, what @neandrake said should work, though you might have to call awesome.evaluate() after setting .list. That should be fixed. There should be a boolean flag about whether it’s open, and in the setter for list, it would check if the widget is open, call evaluate() and maintain selection (store this.index in a variable, call goto after evaluate()). I’m too busy right now, but it’s a simple change, so I could do it after the weekend.

That said, it shouldn’t require so much boilerplate code to do an ajax autocomplete, so I’m not saying something like that shouldn’t be added.

LeaVerou avatar Feb 21 '15 23:02 LeaVerou

Also, even if we don’t (or until we do) add a special API for this, we should add a tutorial for how to do it with the existing API.

LeaVerou avatar Feb 21 '15 23:02 LeaVerou

Well, if I were to review the behavior and API, I think I would start by removing direct modification of the properties/methods, and introduce .set()/.get, which would trigger the necessary operations internally for the update.

An ajax/async api could be nice. Maybe we could work with promises to make the internal async operations easier to work with in that case.

sillero avatar Feb 22 '15 19:02 sillero

It’s pointless to have getters and setters that just get and set properties. That was done in Java because it required API changes to convert your code to getters/setters in the future. The awesomeness with getters/setters in JS is that you can convert plain properties to them at any time and you only need to refactor your own code. I’m using them already where needed, but I won't use them pointlessly, sorry.

LeaVerou avatar Feb 24 '15 21:02 LeaVerou

:+1:

A good API would be something like the filter attribute, but for the whole request. Either with an url with placeholders to be replaced with the input value (see http://autocompletejs.com/examples#2001 for instance) or with a user defined callback returning a promise to defer suggestion list creation.

real34 avatar Feb 25 '15 17:02 real34

I've created an extension that adds AJAX results to Awesomplete. It's really just a proof-of-concept (this version relies on jQuery, overrides the evaluate prototype method, and isn't very configurable) but may be useful to others who are looking to implement AJAX loading: https://github.com/ScottPolhemus/awesomplete-ajax

ScottPolhemus avatar Mar 20 '15 22:03 ScottPolhemus

what about changing the library so that 'list' can be a function that gets passed the input? it would support fetching entries from a server

activeperception avatar Jul 23 '15 13:07 activeperception

@sillero

You could use the fetch API to get the data async which is based on the promise API.

import Awesomeplete from 'awesomplete';

const response = await fetch('data/projects.json');
const result = response.json();

const projectTitles = result.projects.map(project => project.title);

new Awesomeplete(document.querySelector('.js-awesomplete'), {
  list: projectTitles
});

marcobiedermann avatar Sep 08 '16 19:09 marcobiedermann

Also, even if we don’t (or until we do) add a special API for this, we should add a tutorial for how to do it with the existing API.

I was wondering whether you have been able to add a tutorial for this? if so please point me to it.

Otherwise, I have got close by using @neandrake idea ie.

$.ajax({ url: 'xxxxxxxxxa', success : function(data) { awecomp.list=$.parseJSON(data); awecomp.evaluate(); } }); The only issue is that I don't see an existing event on awesomplete from which to fire this ajax call? Ideally I guess I would use an event that fires after the user typed some text but before awesomplete tries to filter it's data - any idea?

Alwigi avatar Feb 14 '19 10:02 Alwigi

https://github.com/LeaVerou/awesomplete/issues/17209 has a CodePen with an example of how to wire this up with stimulus, so the library can remain focused and small.

Lewiscowles1986 avatar Nov 29 '19 02:11 Lewiscowles1986