Skip to content

Conversation

@brianmhunt
Copy link

⚠️ Please note that although this pull will let you use an arbitrary computed function-argument as expected, the API for this pull is incompatible with the 0.10 branch of Typeahead.js.

In other words, while this pull may tide you over, be prepared to refactor for 0.10 and onwards.


Regarding Issue #95, this pull implements a way to address the issue of arbitrary synchronous and asynchronous computed datasets. While it may not be what you had in mind or the direction you want to take, I hope it gives helpful food for thought.

If this were merged the datasets arguments would accept a new computed argument. In the synchronous case that computed option takes a single argument, the query.

this.dataset = new Dataset({
   computed: function (q) { return ['charlie']; }
});

An asynchronous version of computed takes two arguments - the query and a done callback that the user calls with the results they wish to add to the suggestions.

this.dataset = new Dataset({
  computed: function (q, done) {
    setTimeout(function () { done(['alpha', 'beta', 'lucy']); }, 0);
  }
});

Note that the asynchronous version uses the same logic as remote requests to check for duplicate results, but the synchronous version does not do any checks for duplicates.

Neither the synchronous nor asynchronous utilizes the typeahead caching. It is left to the user to determine if and how they want to cache results (I suspect some complex applications in particular may want to do caching and control over limited localStorage resources themselves).

I hope that proves useful and interesting. Cheers.

@brianmhunt
Copy link
Author

It probably also bears mentioning that unlike local and remote which perform a grep on terms, the user-provided 'compute' function itself must determine the relationship between the query argument and results.

This gives more flexibility, but likely also increases the effort and complexity of the user-side. A sophisticated user could replicate the remote argument by employing the transport API themselves.

As well, if both the computed and remote arguments are present on the same dataset, the caching of remote will probably not work as expected. I was not sure what the desired behaviour ought to be when multiple sources other than prefetch (local, remote, computed) were provided for the same dataset argument, so I didn't put much thought into this.

@brianmhunt
Copy link
Author

Just for completeness, here is a trivial jsFiddle demonstrating the asynchronous and synchronous use.

@nagiek
Copy link

nagiek commented May 3, 2013

I tested the async computed field with the Google Places autocomplete. Works great!

This was referenced May 10, 2013
This was referenced May 19, 2013
@brianmhunt brianmhunt mentioned this pull request Jul 6, 2013
@jharding
Copy link
Contributor

FYI I'm not going to accept this pull request. There's nothing wrong with it per se, but I'm in the process overhauling typeahead.js for v0.10 and it'll support this functionality only through a slightly different API.

I'm leaving this open until v0.10 lands though because some people need this functionality right away and this seems like a solid solution to point them towards. Thanks @brianmhunt for the pull request and for pointing people to it when they ask about this sort of functionality. It's much appreciated.

@brianmhunt
Copy link
Author

Thanks for the update @jharding and it's my pleasure. I look forward to the 0.10 branch landing to check out what you've got planned.

Cheers.

@meiraleal
Copy link

This pull request wasn't applied in favor of something different?

@brianmhunt
Copy link
Author

An alternative was proposed for Typeahead version 0.10, but I am not sure what the status of development is.

@jdaily
Copy link

jdaily commented Oct 27, 2013

Got it working in v0.10:

var geocoder = new google.maps.Geocoder();

$('.typeahead').typeahead({
    autoselect: true,
    sections: [{
        name: 'google',
        minLength: 4,
        templates: {
            header: '<h5 class="typeahead-header">Google Results</h5>'
        },
        source: function (q, value) {
            geocoder.geocode({ address: q }, function (results, status) {

                value($.map(results, function (result) {
                    retval = [];
                    retval.push({ value: result.formatted_address });
                    return retval;
                }));
            });
        }
  }]
});

For some reason the header is rendered after the results, I haven't tracked down the cause yet.

@hyspace
Copy link

hyspace commented Dec 14, 2013

@brianmhunt Thanks for your great work. It works for me.

@jharding
Copy link
Contributor

jharding commented Feb 2, 2014

Finally closing this now that v0.10 has been released. Appreciate the work @brianmhunt.

@jharding jharding closed this Feb 2, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

6 participants