Question

I have spent a few unproductive hours with the very painful lack of instructions for Bootstrap (2.3.2) typeahead and have given up for the evening and hope some expert can point me in the right direction.

All the small tests I have fed into my base framework are OK so I know the basics are ok, but whenever I try to use my own feeds and variables it all implodes.. no thats not true.. it does NOTHING!

Here is the live feed running on my dev webserver

http://54.194.148.89:3000/stations/all

and here is the attempt at code

<html>
<head>
    <title>Example</title>
    <script src="http://code.jquery.com/jquery.js"></script>
    <script type="text/javascript" src="js/lib/bootstrap.min.js"></script>
    <script src="http://twitter.github.com/hogan.js/builds/2.0.0/hogan-2.0.0.js"></script>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="css/bootstrap-responsive.min.css">

    <script>

        $('#stations').typeahead([{
            name: 'Search',
            valueKey: 'crs',
            remote: {
                url: 'http://54.194.148.89:3000/stations/all',
                filter: function (parsedResponse) {
                    // parsedResponse is the array returned from your backend
                    console.log(parsedResponse);

                    // do whatever processing you need here
                    return parsedResponse;
                }
            },
            template: [
                '<p class="station_name">{{station_name}} ({{crs}})</p>'
            ].join(''),
            engine: Hogan
        }]);

    </script>


</head>
<body>
<div class="hero-unit">
    <h1>Input Test</h1>

    <input id="stations" autocomplete="off"/>

</div>
</body>
</html>

Ultimately I want the name drop down list to have name (crs) with a value of the crs (I have not even looked into the assigning the value bit yet). Please can anyone put me out of my misery. The end result in future will ideally read the JSON script from the page and assign to a localstorage area for usage, but for now just working will be awesome.

EDIT : Just a clarification, this is open rail data for an open source datapage, and not commercial

Extra edit : When I put this as the body but leaving everything else the same it works fine, so I know typeahead is working as a function

<body>

    <input id="stations" autocomplete="off"/>

    <script>

        var jsonString = '[{"label":"System Administrator","value":"1"},{"label":"Software Tester","value":"3"},{"label":" Software Developer","value":"4"},{"label":"Senior Developer","value":"5"},{"label":"Cloud Developer","value":"6"},{"label":"Wordpress Designer","value":"7"}]';

        var jsonObj = $.parseJSON(jsonString);
        var sourceArr = [];

        for (var i = 0; i < jsonObj.length; i++) {
            sourceArr.push(jsonObj[i].label);
        }

        $("#stations").typeahead({
            source: sourceArr
        });

    </script>

</body>
Was it helpful?

Solution

Your code looks like you are providing options for typeahead.js, but you are not including that library. Instead, you are including the Bootstrap library, which has a typeahead feature. See this SO answer. Perhaps you are doing the reverse of what was going on there.

It sounds like you can use typeahead.js with Bootstrap; you just have to include Bootstrap first:

If you want to use this with a project like Bootstrap, all you have to do is include the JavaScript file for typeahead.js after Bootstrap’s JavaScript file and use our configuration options. [source]

It also sounds like the Bootstrap typeahead functionality was dropped altogether in Bootstrap 3 in favor of using typeahead.js:

Typeahead has been dropped, in favor of using Twitter Typeahead. [source]


You could include typeahead.js like this:

<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://twitter.github.io/typeahead.js/releases/latest/typeahead.js"></script>
<script src="http://twitter.github.io/hogan.js/builds/2.0.0/hogan-2.0.0.js"></script>
<link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap-responsive.min.css">

Note: In addition to including the typeahead.js file, you will need to supply some CSS styles to get it to look nice. (For more information, read this.)


As for why your original code was doing nothing, you need to wrap your code in a document-ready handler. Otherwise it is executed as it is encountered, and at that time the #stations selector does not match anything because the <input id="stations" /> element is not yet part of the DOM. Therefore the input element is never instrumented with the type-ahead functionality.

<script>
#(document).ready(function() {
    $('#stations').typeahead(...);
});
</script>

This is not an issue with your second example because in that case the <script> element comes after the <input> element.


Finally, another reason your second example worked (while your first didn't) is because the "source" option is an option for the Bootstrap .typeahead() function, not the typeahead.js .typeahead() function. If you try that code after including the typeahead.js library, you will get the following error:

Error: one of local, prefetch, or remote is required

OTHER TIPS

I think it might be simpler than I originally thought.

I think the typeahead binding is happening before the dom element is available. Try wrapping your typeahead init in an after documented loaded method - like so:

$(function() {
    $('#stations').typeahead([{ ... }]);
});

then see what you get. In testing on my box, this seemed to at least trigger the ajax call (which failed due to cross-site scripting issues). That cross-site business might bite you later, but at least doing this makes the Ajax call fire (at least for me).

I just looked again at your "working" sample. Notice in that case, the div is declared before the script. That might be why the sample script was at least triggering the Ajax lookup for names while the original code was not.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top