Skip to content

Instantly share code, notes, and snippets.

@adrianhove
Forked from geuis/remote-typeahead.js
Created April 4, 2012 02:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adrianhove/2297184 to your computer and use it in GitHub Desktop.
Save adrianhove/2297184 to your computer and use it in GitHub Desktop.
Remote data querying for Twitter Bootstrap 2.0 Typeahead without modifications, this fork adds the functionality of getting the clicked item's value
<script>
// Charles Lawrence - Feb 16, 2012. Free to use and modify. Please attribute back to @geuis if you find this useful
// Twitter Bootstrap Typeahead doesn't support remote data querying. This is an expected feature in the future. In the meantime, others have submitted patches to the core bootstrap component that allow it.
// The following will allow remote autocompletes *without* modifying any officially released core code.
// If others find ways to improve this, please share.
//User clicked some value by Adrian Hove
var autocomplete = $('#searchinput').typeahead()
.on('keyup', function(ev){
//User clicked some value
$('ul.typeahead li').on('click', function(){
alert($(this).html().replace(/<(?:.|\n)*?>/gm, '')); //Or your function
});
ev.stopPropagation();
ev.preventDefault();
//filter out up/down, tab, enter, and escape keys
if( $.inArray(ev.keyCode,[40,38,9,13,27]) === -1 ){
var self = $(this);
//set typeahead source to empty
self.data('typeahead').source = [];
//active used so we aren't triggering duplicate keyup events
if( !self.data('active') && self.val().length > 0){
self.data('active', true);
//Do data request. Insert your own API logic here.
$.getJSON("http://search.twitter.com/search.json?callback=?",{
q: $(this).val()
}, function(data) {
//set this to true when your callback executes
self.data('active',true);
//Filter out your own parameters. Populate them into an array, since this is what typeahead's source requires
var arr = [],
i=data.results.length;
while(i--){
arr[i] = data.results[i].text
}
//set your results into the typehead's source
self.data('typeahead').source = arr;
//trigger keyup on the typeahead to make it search
self.trigger('keyup');
//All done, set to false to prepare for the next remote query.
self.data('active', false);
});
}
}
});
</script>
<input type="text" id="searchinput" data-provide="typeahead">
@geuis
Copy link

geuis commented Apr 4, 2012

Couple problems with what you're doing here:

str is a global variable. Define it with var =
You're doing a jQuery lookup on every single key stroke.
You're re-defining event handlers on each key stroke. Very bad.

Just move your code out of the keyup function handler. Put it right after where 'var autocomplete' is defined. Also, you may find that .on() won't work once you move it outside. I haven't tested that. Since what we're dealing with here are dynamically created

  • elements, .on() may not see them like .live() would. Look into the jQuery docs about .on() if you notice this stops working.

  • @adrianhove
    Copy link
    Author

    You are correct with the problems part. I took out the code from that segment.

    If I take out the $('ul.typeahead li').on('click', function(){}) from the the keyup, the typehead class in not yet in the DOM. It wont work.

    .live() is deprecated in jq 1.7.

    @geuis
    Copy link

    geuis commented Apr 6, 2012

    Docs from the jQuery site:

    Rewriting the .live() method in terms of its successors is straightforward; these are templates for equivalent calls for all three event attachment methods:

    $(selector).live(events, data, handler); // jQuery 1.3+
    $(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
    $(document).on(events, selector, data, handler); // jQuery 1.7+
    The events argument can either be a space-separated list of event type names and optional namespaces, or an event-map of event names strings and handlers. The data argument is optional and can be omitted. For example, the following three method calls are functionally equivalent (but see below for more effective and performant ways to attach delegated event handlers):

    $("a.offsite").live("click", function(){ alert("Goodbye!"); }); // jQuery 1.3+
    $(document).delegate("a.offsite", "click", function(){ alert("Goodbye!"); }); // jQuery 1.4.3+
    $(document).on("click", "a.offsite", function(){ alert("Goodbye!"); });

    So you should try:

    $(document).on('click', 'ul.typeahead li'', function(){});

    Basically the way .live worked was by listening for the defined events on the common parent DOM node for the dynamic nodes being modified. The version I shared listens on the document and uses "ul.typeahead li" as the context.

    @geuis
    Copy link

    geuis commented Apr 6, 2012

    Docs from the jQuery site:

    Rewriting the .live() method in terms of its successors is straightforward; these are templates for equivalent calls for all three event attachment methods:

    $(selector).live(events, data, handler); // jQuery 1.3+
    $(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
    $(document).on(events, selector, data, handler); // jQuery 1.7+
    The events argument can either be a space-separated list of event type names and optional namespaces, or an event-map of event names strings and handlers. The data argument is optional and can be omitted. For example, the following three method calls are functionally equivalent (but see below for more effective and performant ways to attach delegated event handlers):

    $("a.offsite").live("click", function(){ alert("Goodbye!"); }); // jQuery 1.3+
    $(document).delegate("a.offsite", "click", function(){ alert("Goodbye!"); }); // jQuery 1.4.3+
    $(document).on("click", "a.offsite", function(){ alert("Goodbye!"); });

    So you should try:

    $(document).on('click', 'ul.typeahead li'', function(){});

    Basically the way .live worked was by listening for the defined events on the common parent DOM node for the dynamic nodes being modified. The version I shared listens on the document and uses "ul.typeahead li" as the context.

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