3

I have an existing event heavy page that I am trying to add typeahead support to. The typeahead function works as desired, except that it seems it can only be attached to an input item one time.

The issue is that for simplicity, after certain actions the existing page removes all of the events attached to specific inputs via $('input').off() and then reattaches new event handlers as appropriate for the new context.

This causes a problem in that the reattached typeahead function never seems to fire. (There is a similar but different issue discussed here: Trouble updating Bootstrap's typeahead data-source with post response but this isn't relevant here as I can update the source fine - I just can't get the type-ahead to trigger no matter what I try)

Edit: For clarification - changing the source (as in the linked question) is not the problem - the source on the actual page is a js function that makes a request to the server. The issue is that calling .off() seems to permanently break typeahead, and I can't remove the calls to .off() without having to rewrite most of the page.... The code below and the jsfiddle are simply the shortest code I can devise that demonstrates the issue

There is a working jsfiddle here documenting the problem: http://jsfiddle.net/hz5P3/8/

For future reference, the complete code is below. To briefly document: The input.works text_field has only one typeahead declaration and works fine. The input.no_works has the typeahead function called, then has $('.no_works').off() called to remove all events on this input. The reattached typeahead to this function fails to work at all.

Is there any way to make this second call to typeahead work as expected?

Thanks

Html

<div class="container">
    <div class="hero-unit">
        <h1>Bootstrap jsFiddle Skeleton</h1>
        
         <p>this is a test typeahead that will work</p>         
        <input type="text" class="works" style="margin: 0 auto;">
        
        <p>this is a test typeahead that is updated and will not work</p>
        <input type="text" class="no_works" style="margin: 0 auto;">
    </div>
</diV>​

Javascript

$('.no_works').typeahead({
  source: ["cat", "dog", "mouse"]
});
$('.no_works').off();

$('.no_works').typeahead({
  source: ["cat", "dog", "mouse"]
});

$('.works').typeahead({
  source: ["cat", "dog", "mouse"]
});

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Dave Smylie
  • 2,663
  • 3
  • 25
  • 32

1 Answers1

7

Edit: OK, I understand now.

So, you need to clear the 'typeahead' data from the jQuery object for that element. It might not be the 100% correct way to do it, but it's easy and it works:

http://jsfiddle.net/feXM3/

$('.no_works').typeahead({
  source: ["cat", "dog", "mouse"]
});

$('.no_works').off();

//amir75 added a line here:
$('.no_works').data('typeahead', (data = null))

$('.no_works').typeahead({
  source: ["frog", "cow", "horse"]
});

My original answer: I don't think the 'off' method is removing the old typeahead feature as you expect.

You can do this instead:

//1. store the typeahead object in a variable
var tah= $('.no_works').typeahead({
  source: ["cat", "dog", "mouse"]
});

//2. update the data source
tah.data('typeahead').source = ["frog", "cow", "horse"];

Updated jsfiddle: http://jsfiddle.net/Skp5R/

laher
  • 8,860
  • 3
  • 29
  • 39
  • Sorry - I should have made the question clearer. The source is actually a function making a js request so changing that is not a problem. The .off() is there as part of the existing page - I can't remove the calls to .off() without having to rewrite large chunks of the existing page. The source changing method described here is from the linked question - it doesn't help in this case as changing the source is not related to this issue. – Dave Smylie Sep 05 '12 at 00:03
  • please see my edit. It's worth looking at the source to get an idea of what's going on: https://github.com/twitter/bootstrap/blob/master/js/bootstrap-typeahead.js – laher Sep 05 '12 at 05:42
  • 1
    Cool. That's exactly what it needed to work. Thanks! Reading your solution, I can now see in the source why it breaks as well =) – Dave Smylie Sep 05 '12 at 06:22