[jquery] twitter bootstrap typeahead ajax example

I'm trying to find a working example of the twitter bootstrap typeahead element that will make an ajax call to populate it's dropdown.

I have an existing working jquery autocomplete example which defines the ajax url to and how to process the reply

<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
    var options = { minChars:3, max:20 };
    $("#runnerquery").autocomplete('./index/runnerfilter/format/html',options).result(
            function(event, data, formatted)
                {
                    window.location = "./runner/index/id/"+data[1];
                }
            );
       ..

What do i need change to convert this to the typeahead example?

<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
    var options = { source:'/index/runnerfilter/format/html', items:5 };
    $("#runnerquery").typeahead(options).result(
            function(event, data, formatted)
                {
                    window.location = "./runner/index/id/"+data[1];
                }
            );
       ..

I'm going to wait for the 'Add remote sources support for typeahead' issue to be resolved.

The answer is


i use $().one() for solve this; When page loaded, I send ajax to server and wait to done. Then pass result to function.$().one() is important .Because force typehead.js to attach to input one time. sorry for bad writing.

_x000D_
_x000D_
(($) => {_x000D_
    _x000D_
    var substringMatcher = function(strs) {_x000D_
        return function findMatches(q, cb) {_x000D_
          var matches, substringRegex;_x000D_
          // an array that will be populated with substring matches_x000D_
          matches = [];_x000D_
      _x000D_
          // regex used to determine if a string contains the substring `q`_x000D_
          substrRegex = new RegExp(q, 'i');_x000D_
      _x000D_
          // iterate through the pool of strings and for any string that_x000D_
          // contains the substring `q`, add it to the `matches` array_x000D_
          $.each(strs, function(i, str) {_x000D_
            if (substrRegex.test(str)) {_x000D_
              matches.push(str);_x000D_
            }_x000D_
          });_x000D_
          cb(matches);_x000D_
        };_x000D_
      };_x000D_
      _x000D_
      var states = [];_x000D_
      $.ajax({_x000D_
          url: 'https://baconipsum.com/api/?type=meat-and-filler',_x000D_
          type: 'get'_x000D_
      }).done(function(data) {_x000D_
        $('.typeahead').one().typeahead({_x000D_
            hint: true,_x000D_
            highlight: true,_x000D_
            minLength: 1_x000D_
          },_x000D_
          {_x000D_
            name: 'states',_x000D_
            source: substringMatcher(data)_x000D_
          });_x000D_
      })_x000D_
      _x000D_
_x000D_
})(jQuery);
_x000D_
.tt-query, /* UPDATE: newer versions use tt-input instead of tt-query */_x000D_
.tt-hint {_x000D_
    width: 396px;_x000D_
    height: 30px;_x000D_
    padding: 8px 12px;_x000D_
    font-size: 24px;_x000D_
    line-height: 30px;_x000D_
    border: 2px solid #ccc;_x000D_
    border-radius: 8px;_x000D_
    outline: none;_x000D_
}_x000D_
_x000D_
.tt-query { /* UPDATE: newer versions use tt-input instead of tt-query */_x000D_
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);_x000D_
}_x000D_
_x000D_
.tt-hint {_x000D_
    color: #999;_x000D_
}_x000D_
_x000D_
.tt-menu { /* UPDATE: newer versions use tt-menu instead of tt-dropdown-menu */_x000D_
    width: 422px;_x000D_
    margin-top: 12px;_x000D_
    padding: 8px 0;_x000D_
    background-color: #fff;_x000D_
    border: 1px solid #ccc;_x000D_
    border: 1px solid rgba(0, 0, 0, 0.2);_x000D_
    border-radius: 8px;_x000D_
    box-shadow: 0 5px 10px rgba(0,0,0,.2);_x000D_
}_x000D_
_x000D_
.tt-suggestion {_x000D_
    padding: 3px 20px;_x000D_
    font-size: 18px;_x000D_
    line-height: 24px;_x000D_
    cursor: pointer;_x000D_
}_x000D_
_x000D_
.tt-suggestion:hover {_x000D_
    color: #f0f0f0;_x000D_
    background-color: #0097cf;_x000D_
}_x000D_
_x000D_
.tt-suggestion p {_x000D_
    margin: 0;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>_x000D_
_x000D_
<input class="typeahead" type="text" placeholder="where ?">
_x000D_
_x000D_
_x000D_


To those looking for a coffeescript version of the accepted answer:

$(".typeahead").typeahead source: (query, process) ->
  $.get "/typeahead",
    query: query
  , (data) ->
    process data.options

UPDATE: I modified my code using this fork

also instead of using $.each I changed to $.map as suggested by Tomislav Markovski

$('#manufacturer').typeahead({
    source: function(typeahead, query){
        $.ajax({
            url: window.location.origin+"/bows/get_manufacturers.json",
            type: "POST",
            data: "",
            dataType: "JSON",
            async: false,
            success: function(results){
                var manufacturers = new Array;
                $.map(results.data.manufacturers, function(data, item){
                    var group;
                    group = {
                        manufacturer_id: data.Manufacturer.id,
                        manufacturer: data.Manufacturer.manufacturer
                    };
                    manufacturers.push(group);
                });
                typeahead.process(manufacturers);
            }
        });
    },
    property: 'name',
    items:11,
    onselect: function (obj) {

    }
});

However I am encountering some problems by getting

Uncaught TypeError: Cannot call method 'toLowerCase' of undefined

as you can see on a newer post I am trying to figure out here

hope this update is of any help to you...


Starting from Bootstrap 2.1.0:

HTML:

<input type='text' class='ajax-typeahead' data-link='your-json-link' />

Javascript:

$('.ajax-typeahead').typeahead({
    source: function(query, process) {
        return $.ajax({
            url: $(this)[0].$element[0].dataset.link,
            type: 'get',
            data: {query: query},
            dataType: 'json',
            success: function(json) {
                return typeof json.options == 'undefined' ? false : process(json.options);
            }
        });
    }
});

Now you can make a unified code, placing "json-request" links in your HTML-code.


One can make calls by using Bootstrap. The current version does not has any source update issues Trouble updating Bootstrap's typeahead data-source with post response , i.e. the source of bootstrap once updated can be again modified.

Please refer to below for an example:

jQuery('#help').typeahead({
    source : function(query, process) {
        jQuery.ajax({
            url : "urltobefetched",
            type : 'GET',
            data : {
                "query" : query
            },
            dataType : 'json',
            success : function(json) {
                process(json);
            }
        });
    },
    minLength : 1,
});

when using ajax, try $.getJSON() instead of $.get() if you have trouble with the correct display of the results.

In my case i got only the first character of every result when i used $.get(), although i used json_encode() server-side.


I don't have a working example for you nor do I have a very clean solution, but let me tell you what I've found.

If you look at the javascript code for TypeAhead it looks like this:

items = $.grep(this.source, function (item) {
    if (that.matcher(item)) return item
  })

This code uses the jQuery "grep" method to match an element in the source array. I didn't see any places you could hook in an AJAX call, so there's not a "clean" solution to this.

However, one somewhat hacky way that you can do this is to take advantage of the way the grep method works in jQuery. The first argument to grep is the source array and the second argument is a function that is used to match the source array (notice Bootstrap calls the "matcher" you provided when you initialized it). What you could do is set the source to a dummy one-element array and define the matcher as a function with an AJAX call in it. That way, it will run the AJAX call just once (since your source array only has one element in it).

This solution is not only hacky, but it will suffer from performance issues since the TypeAhead code is designed to do a lookup on every key press (AJAX calls should really only happen on every few keystrokes or after a certain amount of idle time). My advice is to give it a try, but stick with either a different autocomplete library or only use this for non-AJAX situations if you run into any problems.


 $('#runnerquery').typeahead({
        source: function (query, result) {
            $.ajax({
                url: "db.php",
                data: 'query=' + query,            
                dataType: "json",
                type: "POST",
                success: function (data) {
                    result($.map(data, function (item) {
                        return item;
                    }));
                }
            });
        },
        updater: function (item) {
        //selectedState = map[item].stateCode;

       // Here u can obtain the selected suggestion from the list


        alert(item);
            }

    }); 

 //Db.php file
<?php       
$keyword = strval($_POST['query']);
$search_param = "{$keyword}%";
$conn =new mysqli('localhost', 'root', '' , 'TableName');

$sql = $conn->prepare("SELECT * FROM TableName WHERE name LIKE ?");
$sql->bind_param("s",$search_param);            
$sql->execute();
$result = $sql->get_result();
if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
    $Resut[] = $row["name"];
    }
    echo json_encode($Result);
}
$conn->close();

?>


Try this if your service is not returning the right application/json content type header:

$('.typeahead').typeahead({
    source: function (query, process) {
        return $.get('/typeahead', { query: query }, function (data) {
            var json = JSON.parse(data); // string to json
            return process(json.options);
        });
    }
});

You can use the BS Typeahead fork which supports ajax calls. Then you will be able to write:

$('.typeahead').typeahead({
    source: function (typeahead, query) {
        return $.get('/typeahead', { query: query }, function (data) {
            return typeahead.process(data);
        });
    }
});

I went through this post and everything didnt want to work correctly and eventually pieced the bits together from a few answers so I have a 100% working demo and will paste it here for reference - paste this into a php file and make sure includes are in the right place.

<?php if (isset($_GET['typeahead'])){
    die(json_encode(array('options' => array('like','spike','dike','ikelalcdass'))));
}
?>
<link href="bootstrap.css" rel="stylesheet">
<input type="text" class='typeahead'>
<script src="jquery-1.10.2.js"></script>
<script src="bootstrap.min.js"></script>
<script>
$('.typeahead').typeahead({
    source: function (query, process) {
        return $.get('index.php?typeahead', { query: query }, function (data) {
            return process(JSON.parse(data).options);
        });
    }
});
</script>

I am using this method

$('.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 1
},
    {
    name: 'options',
    displayKey: 'value',
    source: function (query, process) {
        return $.get('/weather/searchCity/?q=%QUERY', { query: query }, function (data) {
            var matches = [];
            $.each(data, function(i, str) {
                matches.push({ value: str });
            });
            return process(matches);

        },'json');
    }
});

I've augmented the original typeahead Bootstrap plugin with ajax capabilities. Very easy to use:

$("#ajax-typeahead").typeahead({
     ajax: "/path/to/source"
});

Here's the github repo: Ajax-Typeahead


All of the responses refer to BootStrap 2 typeahead, which is no longer present in BootStrap 3.

For anyone else directed here looking for an AJAX example using the new post-Bootstrap Twitter typeahead.js, here's a working example. The syntax is a little different:

$('#mytextquery').typeahead({
  hint: true,
  highlight: true,
  minLength: 1
},
{
  limit: 12,
  async: true,
  source: function (query, processSync, processAsync) {
    processSync(['This suggestion appears immediately', 'This one too']);
    return $.ajax({
      url: "/ajax/myfilter.php", 
      type: 'GET',
      data: {query: query},
      dataType: 'json',
      success: function (json) {
        // in this example, json is simply an array of strings
        return processAsync(json);
      }
    });
  }
});

This example uses both synchronous (the call to processSync) and asynchronous suggestion, so you'd see some options appear immediately, then others are added. You can just use one or the other.

There are lots of bindable events and some very powerful options, including working with objects rather than strings, in which case you'd use your own custom display function to render your items as text.


I did some modifications on the jquery-ui.min.js:

//Line 319 ORIG:
this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(...
// NEW:
this.menu=d("<ul></ul>").addClass("ui-autocomplete").addClass("typeahead").addClass("dropdown-menu").appendTo(d(...

// Line 328 ORIG:
this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr...
// NEW:this.element.attr....

// Line 329 ORIG:
this.active=a.eq(0).children("a")
this.active.children("a")
// NEW:
this.active=a.eq(0).addClass("active").children("a")
this.active.removeClass("active").children("a")`

and add following css

.dropdown-menu {
    max-width: 920px;
}
.ui-menu-item {
    cursor: pointer;        
}

Works perfect.


Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to twitter-bootstrap

Bootstrap 4: responsive sidebar menu to top navbar CSS class for pointer cursor How to install popper.js with Bootstrap 4? Change arrow colors in Bootstraps carousel Search input with an icon Bootstrap 4 bootstrap 4 responsive utilities visible / hidden xs sm lg not working bootstrap.min.js:6 Uncaught Error: Bootstrap dropdown require Popper.js Bootstrap 4 - Inline List? Bootstrap 4, how to make a col have a height of 100%? Bootstrap 4: Multilevel Dropdown Inside Navigation

Examples related to jquery-autocomplete

Style jQuery autocomplete in a Bootstrap input field How to get jQuery dropdown value onchange event twitter bootstrap typeahead ajax example jQuery autoComplete view all on click?

Examples related to jquery-ui-autocomplete

How to use source: function()... and AJAX in JQuery UI autocomplete How to get jQuery dropdown value onchange event Styling JQuery UI Autocomplete jQuery UI autocomplete with JSON twitter bootstrap typeahead ajax example Limit results in jQuery UI Autocomplete jQuery UI autocomplete with item and id

Examples related to typeahead.js

twitter bootstrap 3.0 typeahead ajax example twitter bootstrap typeahead ajax example