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.
This question is related to
jquery
twitter-bootstrap
jquery-autocomplete
jquery-ui-autocomplete
typeahead.js
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_
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_
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.
Source: Stackoverflow.com