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

Trigger custom events #68

Closed
jharding opened this issue Mar 1, 2013 · 33 comments
Closed

Trigger custom events #68

jharding opened this issue Mar 1, 2013 · 33 comments
Assignees
Milestone

Comments

@jharding
Copy link
Contributor

jharding commented Mar 1, 2013

There's a handful of issues asking for something along the lines of a "selection callback". While I agree this is necessary, I don't think adding an option like onSelection is the best way to go about it. Instead, I think triggering custom events on the typeahead input is the way to go. It's a more extensible approach and it won't pollute the options hash.

I'm creating this ticket to start brainstorming what events we need to trigger. The only 2 I can think of right now are:

If there's anything else you'd like an event triggered for, leave a comment in this issue.

@ghost ghost assigned jharding Mar 1, 2013
@r4vi
Copy link
Contributor

r4vi commented Mar 1, 2013

for the suggestion selected event, I'd find it useful if the event supplied the entire datum selected instead of just the value

@jharding
Copy link
Contributor Author

jharding commented Mar 1, 2013

That's the plan 😄

@seiz
Copy link

seiz commented Mar 1, 2013

I could think of:

  • suggestions updated (i.e. prefetched data is cached, a search was done by the user and the suggestions have been updated)
  • prefetched data error (when the json couldn't be retrieved if "prefetched data loaded" could return a success or error state, that'd be even better )
  • remote data loaded (not sure if i understand remote correctly yet and wether that data is traveling through typeahead at all)

@r4vi
Copy link
Contributor

r4vi commented Mar 1, 2013

Oh just thought of another one; though probably not appropriate for the typeahead input.
It'd be interesting to add more context once a template has been rendered for each datum.
1 Home
Take this friends app for example:

If the dataum was found in the local cache then we would not know if the friend was online. But we could subscribe to a onTemplateRendered to let us look up the online status of each suggestion and fill it in after the fact? Maybe there's a better way, where we have an event to update the context before it is rendered with more info?

@bodinsamuel
Copy link

On "nothing left" when the request typed is too specific and there is nothing to display.
It could be usefull to help lost user, in my case I find it very usefull, even more if I could temporarily add a message in the suggestion box.

@jharding
Copy link
Contributor Author

jharding commented Mar 4, 2013

Would it be alright if not all of the events were triggered on the typeahead input element? Datasets are encapsulated away from the DOM, so it wouldn't be trivial to trigger events like prefetched on the input element. Rather, those kinds of events would have to be triggered on the document.

@jharding
Copy link
Contributor Author

jharding commented Mar 4, 2013

@r4vi for the use case you described, you'd probably want to rely on remote data and turn caching off.

@seiz
Copy link

seiz commented Mar 4, 2013

@jharding That'd be all right for me, as long as out could find out which typeahead instance triggered the event (in the rare cases where you't have multiple typeahead instances in one document).

@r4vi
Copy link
Contributor

r4vi commented Mar 5, 2013

@jharding agree on the use-case I mentioned, was just trying to think of ways people might use it.
WRT events like prefetched on the document, no problem but what if you had more than one typeahead?

wouldn't it be better to return an object that you could watch for events on initialization of typeahead?
e.g.:

var tt-events = $('input').typeahead({...})
$(tt-events).on('prefetched', function(..) {..})

which, on second thought, does break jQuery chaining, so maybe something like this would be better

var to_notify = new Object()
$('input').typeahead({...
notify: to_notify })
$(to_notify).on('prefetched', function(..) {..})

@jharding
Copy link
Contributor Author

jharding commented Mar 5, 2013

I was imagining the prefetched event would be triggered per dataset, not per typeahead. So if you're typeahead was initialized with 2 datasets that included prefetched data, you'd want to wait until the prefetched event for both of those datasets has been triggered before you did anything crazy. It may be better to trigger per typeahead though, even if it is a little trickier to implement.

I'm not a fan of returning an object on typeahead initialization because it breaks jQuery chainability.

@r4vi
Copy link
Contributor

r4vi commented Mar 5, 2013

we should consider the implication of datasets with the same name being used in more than one typeahead; what if you have two typeaheads using a common dataset? e.g.

$('input.t1').typeahead([
  {
    name: 'accounts',
    prefetch: 'https://twitter.com/network.json',
    remote: 'https://twitter.com/accounts?q=%QUERY'
  },
  {
    name: 'trends',
    prefetch: 'https://twitter.com/trends.json'
  }
]) ;
// and
$('input.t2').typeahead(
  {
    name: 'accounts',
    prefetch: 'https://twitter.com/network.json',
    remote: 'https://twitter.com/accounts?q=%QUERY'
  }) ;

 $(document).on('tt.prefetched', function(dataset) {
   console.log(dataset.name)
}

Would this give us the following output?
> accounts
> trends
> accounts
if so, how do we know which typeahead it relates to? should dataset have a .typeahead attribute?

This also raises the question of deduplicatng the dataset persistent cache, should we hit /accounts twice in this scenario, is there a race condition here? what if we had different URLs for accounts in both typeaheads.... should we namespace the persistent cache by typeahead (or construct a key/hash for each one based on url?)

I'd say for 0.9 go for events on the document for each dataset and see what feedback we get from people doing weird stuff.

@devonray
Copy link

I could imagine a use case for exposing a "selectionHighlighted" event. This would allow other portions of the application to know when a selection is highlighted (via mouse hover or keyboard navigation). By knowing when a selection is highlighted, you can make other portions of the UI respond (e.g. updating an image preview based on the highlighted selection) all without typeahead's knowledge. I don't know what this event would be called, but it would clearly happen before the 'selected' event.

As far as the means for event communication/propagation, I could see something like r4vi's idea of passing in an event dispatcher as an argument to typeahead. This would allow the developer to have flexibility with regards to event management. And example with backbone would look like the following, for example:

var MyEventDispatcher = _.clone(Backbone.Events);
/* ...application code... */
$('input').typeahead({
  dispatcher: MyEventDispatcher
});
MyEventDispatcher.on('typeaheadSelectionHighlighted', updateSelectionPreview);

I used the Backbone.Events object here, but it leaves it to the developer to decide what kind of object to use.

@haberbyte
Copy link

👍

I would also see use cases of this.
In general, i would love events similar to those found in Jquery-UI's autocomplete widget.

See http://api.jqueryui.com/autocomplete/

It would be awesome to have at least those:

  • change: triggered when a selection is made
  • select: triggered when a selection is highlighted
  • open: triggered when the suggestions menu opens
  • close: triggered when the suggestions menu closes

I would differentiate between 'change' and 'close' because a user might close the suggestions by clicking somewhere else without actually changing the selection.

What do you think?

@nofxx
Copy link

nofxx commented Mar 11, 2013

@jharding last thing in my deadline is this custom event on click/enter, thinking about pushing something today? ;)
More than happy to test...

EDIT: playing with #22 and #100 in the while

@jharding
Copy link
Contributor Author

Nothing is going to ship today, the hope is to have v0.9.0 out next Monday.

@jharding
Copy link
Contributor Author

@nofxx I started to work on implementing this stuff, check out #106 – it triggers an event on selection.

@jharding
Copy link
Contributor Author

we should consider the implication of datasets with the same name being used in more than one typeahead; what if you have two typeaheads using a common dataset?

@r4vi datasets are identified by name, so in your example code, only one accounts dataset would be initialized. The initialization code looks something like this:

var datasetCache = {};

function initialize(datasetDef) {
  var dataset;

  if (datasetCache[datasetDef]) {
    dataset = datasetCache[datasetDef];
  }

  else {
    dataset = new Dataset(datasetDef);
    datasetCache[datasetDef.name] = dataset;
  }
}

In the next revision of the README, I'm hoping to make it clear that this is what's going on.

@nofxx
Copy link

nofxx commented Mar 11, 2013

Just by overwritting _handleSelection I could make everything work here.
Functionality: Select a item goes via click/enter goes directly to the page, enter submits form while on input (inspired by github search let's say ;)
Just need to hack a lil to get my selected item to it's respective json object.
Something like this would be great:

remote: ...
handler: 
  handle: (item) ->
    # have fun with item 

Works like the 'engine' option.

@nofxx
Copy link

nofxx commented Mar 11, 2013

@jharding damn, hope to actually learn js someday...nice code.
getSuggestionData looks way better, using the object around.
That'll for sure suffice the click/enter funcionality.
Just need to figure out now how to submit the input's form when the click came from it.

@jharding
Copy link
Contributor Author

@nofxx would something like this work:

$('.typeahead').typeahead({ /* ... */ })
.on('typeahead:selected', function($e) {
  var $typeahead = $(this),
      $form = $typeahead.parents('form').first();

  $form.submit();
});

@r4vi
Copy link
Contributor

r4vi commented Mar 11, 2013

I'm doing exactly that with my current autocomplete plugin

@nofxx
Copy link

nofxx commented Mar 12, 2013

@jharding thanks for the code , it's pasted here. I'll try with 0.9, my overwrited version is working til there.
Thank you.

@jharding
Copy link
Contributor Author

For those of you who are interested, here's a list of events that will be triggered in v0.9.0:

  • typeahead:initialized – Triggered the typeahead has been initialized. If the typeahead relies on a dataset that needs to prefetch data, this event won't be triggered until after that has happened, otherwise it'll happen immediately.
  • typeahead:selected – Triggered when a suggestion from the dropdown menu is selected. The suggestion object will be passed as an argument.
  • typeahead:opened – Triggered when the typeahead dropdown menu is opened.
  • typeahead:closed – Triggered when the typeahead dropdown menu is closed.

All of these events will be triggered on the typeahead input.

@devonray
Copy link

@jharding Which does "selected" mean:

  1. When the suggestion is highlighted
  2. When a suggestion is clicked/enter key pressed

On Wed, Mar 13, 2013 at 1:23 AM, Jake Harding [email protected]:

For those of you who are interested, here's a list of events that will be
triggered in v0.9.0:

typeahead:initialized – Triggered the typeahead has been initialized.
If the typeahead relies on a dataset that needs to prefetch data, this
event won't be triggered until after that has happened, otherwise it'll
happen immediately.
-

typeahead:selected – Triggered when a suggestion from the dropdown
menu is selected. The suggestion object will be passed as an argument.

typeahead:opened – Triggered when the typeahead dropdown menu is
opened.

typeahead:closed – Triggered when the typeahead dropdown menu is
closed.

All of these events will be triggered on the typeahead input.


Reply to this email directly or view it on GitHubhttps://github.com//issues/68#issuecomment-14825109
.

Devon Ray Williams :: Devon Ray Music http://devonraymusic.com/ :: How to
Reach Me http://protocol.by/Devon

@r4vi
Copy link
Contributor

r4vi commented Mar 13, 2013

@devonray I believe it's (2)

@jharding
Copy link
Contributor Author

2

On Wednesday, March 13, 2013, Ravi Kotecha wrote:

@devonray https://github.com/devonray I believe it's (2)


Reply to this email directly or view it on GitHubhttps://github.com//issues/68#issuecomment-14837380
.

@rayui
Copy link

rayui commented Mar 13, 2013

Mr Harding... is the event code now in 0.9.0 branch? I can't see it...

@jharding
Copy link
Contributor Author

Not yet, it'll be in there sometime tonight.

@jharding
Copy link
Contributor Author

@rayui the event code is now available in integration-0.9.0.

@KarthikDot
Copy link

I've been playing around with typeahead, and another event that might make sense is if some text is typed in, but no match is found.

@jharding
Copy link
Contributor Author

FYI, all future discussion concerning custom events should happen over at #130.

@dripisforever
Copy link

Hey, @r4vi , @jharding , @ankane
I'll be grateful, if you can reply! Can you explain:
I use searchkick (backend Ruby On Rails) with typeahead and don't know a place where to add things like:

<% user.avatar %> 
<% user.followers.count %>

image

I want to develop autocomplete searching with displaying user's avatar like above!

@joshuaedwardcrowe
Copy link

You need to place them in the objects that are passed to typeahead (or Bloodhound if you're using that).

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

No branches or pull requests