How to Use JSON Objects With Twitter Bootstrap Typeahead
November 5th, 2012
Twitter’s Bootstrap is all the rage these days, and for good reason. It’s chock full of aesthetically pleasing, easily customizable styles and useful widgets. Among the latter you’ll find typeahead, a widget for auto-suggesting possible values in response to user input.
Typeahead Using an Array of Strings
Bootstrap’s standard implementation of typeahead uses an array of strings to provide suggestions:
html:
<body> <input id="search"/> </body>
JavaScript:
var colors = ["red", "blue", "green", "yellow", "brown", "black"]; $('#search').typeahead({source: colors});
Here’s what the widget looks like:
The implementation is simple, clean, and works as expected. What more could you want?
Typeahead Using an Array of Objects
Well, sometimes working with strings is too limiting. For example, consider a scenario where you want the user to enter a US state and you need to capture the two-letter state abbreviation once the selection is made (if the user enters “California”, you’ll store “CA”):
To build this feature we could use an array of objects which contain both the name of the state and the abbreviation:
var stateList = [ {"stateCode": "CA", "stateName": "California"}, {"stateCode": "AZ", "stateName": "Arizona"}, {"stateCode": "NY", "stateName": "New York"}, {"stateCode": "NV", "stateName": "Nevada"}, {"stateCode": "OH", "stateName": "Ohio"}, ... ];
Bootstrap exposes a set of overridable options we can leverage to implement typeahead with an array of objects:
- Source
- Matcher
- Sorter
- Highlighter
- Updater
It’s important to note that you can probably leverage Bootstrap’s own implementations for pretty much everything except source
and updater
. That said, in this example, we will implement all of them using the template below:
$('#search').typeahead({ source: function (query, process) { // implementation }, updater: function (item) { // implementation }, matcher: function (item) { // implementation }, sorter: function (items) { // implementation }, highlighter: function (item) { // implementation }, });
1. Source
Let’s begin with source
. This option specifies the data set to use for the auto-suggest list. It can take either an array of strings (which we saw in the first example) or a function:
source: function (query, process) { states = []; map = {}; var data = [ {"stateCode": "CA", "stateName": "California"}, {"stateCode": "AZ", "stateName": "Arizona"}, {"stateCode": "NY", "stateName": "New York"}, {"stateCode": "NV", "stateName": "Nevada"}, {"stateCode": "OH", "stateName": "Ohio"} ]; $.each(data, function (i, state) { map[state.stateName] = state; states.push(state.stateName); }); process(states); },
This function takes two parameters: query
and process
(I’ll talk about both in a bit). The first thing we do is get data
, an array of state objects. Though I’ve hardcoded contents of data
inside the function in this example, in a real production app it would come from the server.
Next, we map state names to the corresponding objects using two global variables, map
and states
. This is necessary because Bootstrap needs a list of strings to actually display auto suggestions (states
array), while we need to get the original objects (stored in the map
). Obviously, names of your objects need to be unique for this to work.
Finally, we call Bootstrap’s process()
function with the states
array. Process()
orchestrates the event loop for typeahead (by calling matcher
, sorter
, etc) and sets up the auto-suggest list displayed to the user.
You may have also noticed that we didn’t use query
input parameter in this example. Typically, query
would be used to implement server-side filtering of the auto-suggestion list because it contains the search string entered by the user.
2. Matcher
Next, let’s implement the matcher()
. This function is used by Bootstrap to check if the search string typed by the user matches anything in the source
list. Its purpose is to filter the auto-suggest list to only the relevant values:
matcher: function (item) { if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1) { return true; } }
The implementation above is fairly trivial. We simply take user’s input (contained in this.query
) and check to see if it exists anywhere in the item
. Conversion of both strings to lower case is needed because the user is unlikely to expect case to be considered when matching terms.
3. Sorter
The Sorter
function is responsible for sorting the list of suggestions filtered by the matcher:
sorter: function (items) { return items.sort(); }
Again, I should note that my implementation is quite simplistic. Sorting suggestions is usually a more elaborate affair. For example, Bootstrap’s own implementation considers whether user input is found at the beginning of the suggested string and whether the match was case sensitive.
4. Highlighter
Bootstrap uses highlighter
to highlight user’s input within auto-suggested results. We can use a simple regex match to find and bold user’s input:
highlighter: function (item) { var regex = new RegExp( '(' + this.query + ')', 'gi' ); return item.replace( regex, "<strong>$1</strong>" ); }
5. Updater
Finally, we get to the updater
. This function is called by Bootstrap once the user selects an item, which gives us a chance to do something with the selection. In this case, we’d like to record the selected state abbreviation in a global variable selectedState
before returning the item
:
updater: function (item) { selectedState = map[item].stateCode; return item; }
Note of caution: it’s very important that you return the item
because that’s the value used by Bootstrap to set the input
box.
References:
https://github.com/twitter/bootstrap/pull/3682
http://twitter.github.com/bootstrap/javascript.html#typeahead
You may also like:
Did you love / hate / were unmoved by this post?
Then show your support / disgust / indifference by following me on
Twitter!
This post got 86 comments so far. Care to add yours?
Not sure where the variable ‘mapped’ comes from in the update event.
Looks like you should use “map[item].stateCode” instead of “mapped[item].value” in your update event.
Thanks for this! After figuring that last part out, it helped a great deal and I’ve referenced it on StackOverflow here: http://stackoverflow.com/a/13277173/303659
Cheers!
Thank you very much for the correction Gerbus, I’ve updated the article appropriately.
Alex, apparently you didn’t fix the mapped[item] in your code, anyway after fixing it’s working like a charm, thanks a lot to both of you! (Alex & Gerbus)
Hi Biesior, I did actually fix the updater() to use stateCode:
updater: function (item) {
selectedState = mapped[item].stateCode;
return item;
}
Are you seeing something different? Anyway, thanks for your comment, glad you found the tutorial useful.
Yes it should be “map” and not “mapped”
Yes! Yes! Thanks a lot… I’ve not tested yet but I think, I hope that is the missed piece of my puzzle. I gonna test it now…
Also, the variable for map needs to be declared outside of your process function (globally) so that it can later be referenced in the updater function, unless I am missing something. This was the only way I could get it to work. Thanks for the tutorial though! Great job.
Hi Jake, good tip and thank you for reading!
Hi Jake, you don’t need to make the variable for map global. The documentation:
http://twitter.github.com/bootstrap/javascript.html#typeahead
says that the updater function has the scope of the typeahead instance.
(I’ve tried and it really works 🙂 )
Hi Alex,
Is there a way to make it work without the item’s labels being unique?
If the typeahead is used to find people then unique names are not secure…
Thank you!
Hi Pachocho, I’m not sure how you’d do this since you need some way to unambiguously identify a value in the map. Sorry.
I’ve found an approach for this, and written it up here: http://stevedrivendevelopment.com/2013/02/10/using-twitter-bootstrap-typeahead-to-select-a-keyvalue-pair-not-a-string/
it uses the ‘highlighter’ function and a little bit of JSON. Highlighter is a bit of a misnomer — it’s actually an arbitrary function for re-writing the text that appears in the dropdown.
Set the source option to a function returning an array of JSON-serialized name/value pairs;
return [
JSON.stringify({ name:”mylabel”, value: 4 }}
];
Set the highlighter to return just the name, not the value;
highlighter: function(item) {
return JSON.parse(item).name;
}
Set the matcher to return things that match the right name;
matcher: function (item) {
return JSON.parse(item).name.toLocaleLowerCase().indexOf(this.query.toLocaleLowerCase()) != -1;
}
Use the updater to catch the selected item;
updater: function (item) {
alert(JSON.parse(item).value);
return JSON.parse(item).name;
}
This pattern lets you search for text but return a corresponding key.
Hi Steve, thank you very much for the comment, your method looks very promising.
Thanks heaps for this. Just what i was looking for.
I wish all the bootstrap plugins had formal documentation and examples for each option, so i don’t need to google everything. 🙂
You’re welcome Ryano, glad you found it useful.
Just what I need; that one important thing that’s missing for bootstrap newbies such as myself: examples. 🙂
PS:
Needs to change “mapped” to “map” in the updater function; and voila!
Very helpful post..Found this after a lot of struggling through other links. Wish I could have found this earlier.
They should make something like this part of the official documentation.
Thank you very much Ankur, glad you found it useful!
You’re storing a map and an array of the source data in there with the same data. Basically, you’re increasing the memory load on the browser!
You’re right GroovyBoy, I am increasing the load. That said, if you have a way that doesn’t increase the load, I’m all ears. thanks
Thanks a lot for your post, it did helped get implemented typeahead into my app.
You’re welcome Ronald, glad it was helpful!
Helpful article thank you. Do you know if there is a way to prevent typeahead from updating the field with the selected value?
Ty for posting.
I have a user JsonGet User Source;
(Just Display Name)
But i need autocomplate(typehead) clicked: windowlocation.href=xxx.com/xxx/?user=source_id
Note: I have Loop in Dislay Name and id, but i dont know this array values and recidet fonksiyon. Thx
Thx, my ask end from Updater 😉 ty Alex very nice.
Hi Onur, I’m having a bit of difficulty understanding your question. Are you saying that you have a JSON object
user
, which contains a property calledsource
and you’d like to use it to construct and redirect to a url?If that’s the case, you’d probably want to do something like this in the
updater()
:Hope this helps, thanks
Hi Alex,
I’ve followed your code above and altered it to pull from my Database, I’m getting an odd issue though, If I type fast enough into the text box I will sometimes get double results, Do you know why this might be? I assume it’s something to do with the global state and map variables though I’m not sure
Cheers
Scott
By changing the state variable in the source function to var state = [] I seem to have fixed my own issue, but I’m not sure if this will effect other things later on, I’ll guess I’ll play around some more and see! Thanks
Thanks for that!, it worked for me.
Although I find it weird that nobody else is experiencing this problem (problem: typing fast gives repeated results)
Hi Scott,
I’m having double results as well but you solution didn’t work for me. Where exactly you set the variable to []?
I’m on things for too long already, I’m starting to consider using another solution…
Absolutely great article, thank you so much.
Its very rare to find such precise, clear and illustrated documentation online.
Thank you very much!
I would like to add to excellent article, cascading multiple typeahead fields:
Assume you have a subject,course, and code.
– Subjects populates in itself
– Course populates with the Subject’s selection
– Section populates with the Course and Subject’s selection
Notice we need the code and not the name from each json array of the form [ {code: value, name: value}……]
Assume you have three fields and want to cascade them using type ahead, here is an elegant solution, by reusing your code. In this case all the data comes from server.
The only thing deserves an explanation is this code in the updater :
var name_box = $(‘#class-details-subject’).val();
var name_data = $(‘#class-details-subject’).data(‘name’);
if ( name_box != name_data ) {
$(‘#class-details-subject’).data(‘code’, name_box);
}
This piece makes sure we obtain the most recent data in the input fields. Hope it helps
$(‘#class-details-subject’).typeahead({
source: function (query, process) {
// implementation
return $.getJSON(
‘/subjects_like’ ,
{ query: query },
function (data) {
subjects = [];
map = {};
$.each(data, function (i, subject) {
map[subject.name] = subject;
subjects.push(subject.name);
});
process(subjects);
});
},
updater: function (item) {
// implementation
$(‘#class-details-subject’).data(‘code’, map[item].code);
$(‘#class-details-subject’).data(‘name’, map[item].name);
return item;
},
matcher: function (item) {
// implementation
if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1) {
return true;
}
},
sorter: function (items) {
// implementation
return items.sort();
},
highlighter: function (item) {
// implementation
var regex = new RegExp( ‘(‘ + this.query + ‘)’, ‘gi’ );
return item.replace( regex, “$1” );
},
});
$(‘#class-details-course’).typeahead({
source: function (query, process) {
var name_box = $(‘#class-details-subject’).val();
var name_data = $(‘#class-details-subject’).data(‘name’);
if ( name_box != name_data ) {
$(‘#class-details-subject’).data(‘code’, name_box);
}
var subject = $(‘#class-details-subject’).data(‘code’);
return $.getJSON(
‘/courses_like?subject=’ + subject,
{ query: query },
function (data) {
return process(data);
});
}
});
$(‘#class-details-section’).typeahead({
source: function (query, process) {
var name_box = $(‘#class-details-subject’).val();
var name_data = $(‘#class-details-subject’).data(‘name’);
if ( name_box != name_data ) {
$(‘#class-details-subject’).data(‘code’, name_box);
}
var subject = $(‘#class-details-subject’).data(‘code’);
var course = $(‘#class-details-course’).val();
return $.getJSON(
‘/sections_like?subject=’ + subject + ‘&course=’ + course ,
{ query: query },
function (data) {
return process(data);
});
}
})
Hope it helps
Eric Echeverri
That’s a great tip, thank you very much Eric.
A well documented write up. If i had come across it a day before i would have saved lot of time. Thanks Alex you saved my day..
I have another problem in FF where, if i press keydown it traverse alternate data only. i.e, next and prev is not working accordingly. It is bootstrap typeahead bug. Any thoughts on this.
Hi Anusha, glad you found it useful. As for the bug you mention, I haven’t seen it myself though I don’t use Firefox on a regular basis. Sorry.
brilliantly simple! I created a more complex “map” object and I am now able to set the value of a hidden field and update a photo one the code hits the “updater” function. I also hijack the form’s submit event to check that the value of the textbox and the hidden field are valid. I prevent the submission of the form whenever those fields do not match any of the allowed values. Pretty sweet really.
One thing to note guys, is that the source function runs every time the value of textbox changes. This being said, if you have no need to run ajax to look-up new data, it would be best to move the algorithm for building the states array and map object to outside the typeahead source function.
Hi Angel, yes, there’s a lot of cool stuff you can do with this technique. Thank you very much for sharing!
Hello,
There is one thing missing, I scroll the comment, but didn’t see anything about that… What happen if the user clear it out the field?? The updater only update de hidden field when there is a match but in my case of use since there is no zero entry in value there is no match so the hidden field value stays to the last match label entry in the field… I know it pretty dumb to not complete a form, but you know with users you never know!!
Gus
Yes you’re right. I have the same issue. Did you manage to get it work? I think of reseting the value of the hidden input each time the user changes the Typeahead box (delete or add a letter) but I don’t know if it’s too much… and also the Change event must happens before the Updater function of the Typeahead…
I think I manage it like that :
$(‘input#%(table_name)s_%(field_name)s_ac’).blur(
function(){
if($(this).val().length==0) {
$(‘#%(table_name)s_%(field_name)s’)
.find(‘option’)
.remove()
.end();
}
else if($(‘#%(table_name)s_%(field_name)s’).val()!=mapped[$(this).val()]) {
$(‘#%(table_name)s_%(field_name)s’)
.find(‘option’)
.remove()
.end();
}
});
Chaining : http://stackoverflow.com/questions/47824/how-do-you-remove-all-the-options-of-a-select-box-and-then-add-one-option-and-se
Sorry, I didn’t answer earlier…
Gus
I handled this with a keyup handler:
$(‘#search’).keyup(function() {
selectedState = ”;
});
Hello Alex..
Amazing article this is. Helping me a lot with typeahead functionality that I am using in my project.
I have some doubts. I want to append selected JSON object to html attribute. I tried doing it in updater function but it does not work.
Here is the scenario. Patient information is stored in JSON. I use typeahead to search patient name. When I select patient name, it will show Patient name, age, etc information in with some id..
Any way to achieve this?
Hi Rahul,
Thanks for reading, glad you found it useful. To answer your question, there are many ways to bind JSON data to HTML. Probably the easiest is using jQuery.
Suppose you have the following HTML to display patient data:
Also suppose that the JSON representing patient data stored in your
map[]
looks like this:Now, once the patient is selected, you can do the following in the
updater()
:Hope this helps.
Thank you so so much for a prompt help. Much much much appreciated. Glad I read blogs of people like you. Added your blog to my feed.. 🙂
I forgot to return item; that was the problem I guess.
Keep in touch,
Regards,
Rahul P
(Wrapcode.com)
hi rahul i have same problem .. but i new to yii and json. from array i got value and while from data base i dnt know how to get it.. if some documentation available pleas share this.
regards,
chirag
I copy and paste and it didn’t work =(
$(‘input.autocomplete’).typeahead({
source: function (query, process) {
states = [];
map = {};
var data = [
{“stateCode”: “CA”, “stateName”: “California”},
{“stateCode”: “AZ”, “stateName”: “Arizona”},
{“stateCode”: “NY”, “stateName”: “New York”},
{“stateCode”: “NV”, “stateName”: “Nevada”},
{“stateCode”: “OH”, “stateName”: “Ohio”}
];
$.each(data, function (i, state) {
map[state.stateName] = state;
states.push(state.stateName);
});
process(states);
},
matcher: function (item) {
if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1) {
return true;
},
sorter: function (items) {
return items.sort();
},
highlighter: function (item) {
var regex = new RegExp( ‘(‘ + this.query + ‘)’, ‘gi’ );
return item.replace( regex, “$1” );
},
updater: function (item) {
selectedState = map[item].stateCode;
return item;
}
});
Sorry to hear that Alex, what’s the specific error you’re getting?
In the matcher
item is undefined
if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1) {
Ok This is my problem
$(‘:input.autocomplete’).typeahead({
minLength: 3,
source: function(query, process) {
objects = [];
map = {};
var data = [{“id”:803,”label”:”Imaginaria Sac”},{“id”:804,”label”:”One Sac”},{“id”:805,”label”:”All Feliz Sac”}];
$.each(data, function(i, object) {
map[object.label] = object;
objects.push(object.label);
});
process(objects);
},
updater: function(item) {
$(‘#idclien’).val(map[item].id);
return item;
}
});
I understand this, but it doesn’t work. I only want save the ID in the hidden field
The error is:
Item is undefined
return ~item.toLowerCase().indexOf(this.query.toLowerCase())
bootstrap.js (lÃnea 1652)
Thanks
Is missing you the full version of typeahead script, just add it in your script.
You can download here:
https://github.com/twitter/bootstrap/blob/master/js/bootstrap-typeahead.js
Awesome tutorial. Really good job
Thank you Alexander!
Alex,
I’m trying to create a search bar for my own website. The goal is to have the typeahead provide choices and when the user selects a choice, it takes them to a new page. At the moment the typeahead works and I get redirected but using Firebird it says it is undefined. I’m wanted to save the url address with the search query words, but I’m not sure if this is right.
$(function(){
var map = {};
var pages = [];
$(“.typeahead”).typeahead({
source: function ( query, process ) {
$.ajax({
url: ‘json/ortho.json’
,prefetch: ‘json/ortho.json’
,cache: false
,success: function(data){
map = {};
pages = [];
_.each( data, function(item, ix, list){
pages.push( item.name );
map[ item.name ] = item.id;
});
process( pages );
}
});
}
,matcher: function (item) {
if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1) {
return true;
}
}
,sorter: function (items) {
return items.sort();
}
,highlighter: function (item) {
var regex = new RegExp( ‘(‘ + this.query + ‘)’, ‘gi’ );
return item.replace( regex, “$1” );
}
,updater: function ( selectedName ) {
$( “#websitehref” ).val( map[ selectedName ] );
return window.location.href = $(selectedName).attr(“id”);
}
});
});
And the JSON file
[
{ “id”:”#index.html”, “name”:”invisalign” }
,{ “id”:2, “name”:”braces” }
,{ “id”:3, “name”:”seperators” }
,{ “id”:4, “name”:”spacers” }
,{ “id”:5, “name”:”brushing” }
,{ “id”:6, “name”:”nance” }
,{ “id”:7, “name”:”fees” }
,{ “id”:8, “name”:”retainers” }
]
I used some of your code and Adam’s code from fusiongrokker.com. I hope you can help me get a better idea on this thanks…
John
Great Article – Thank you.
Thanks for reading Neil.
Thanks for the tutorial its really nice but I can’t figure out this error. can anyone help. I have tried the suggestion by Cinthia Davalos
Uncaught TypeError: Cannot call method ‘toLowerCase’ of undefined
Thanks a lot. Was helpful
Helpful article thank you. Do you know if there is a way to prevent typeahead from updating the field with the selected value?
[…] Objetos jSON en Typeahead (Autocomplete) de Twitter Bootstrap […]
Do you know if is there a present callback for mouse over the li?
Nice Explaination…But I have one query..
How we can force user to select value from typeahead result list only..and not allowing him to write any other value?
Thanks Dhiraj. To answer your question, you control what the user selects in the updater(). In fact, the implementation in this example is essentially restricting the user to select a value from the result list because
map[item]
will be null for anything not in the list.You can be more extreme and not return a valid value from updater() unless it’s in the list, but that would make for a very awkward user experience.
In my case, I’m using Knockout.js for data binding, so my view-model already has a collection of the objects that was created in your code as a global (the ‘map’ variable). So instead of creating a fresh copy, I’m just referring to that mapping. As another commenter noted, the source function is called on every change to the textbox, so this is a bit faster to execute, not that it matters a whole lot on fast computers and non-IE 8 web browsers.
Also, since the collection of objects is built externally, my source method is just:
var items = thisCollectionIHave.map(function (item) {
return item.name;
});
process(items);
which uses the jQuery map() function to pretty simply pull the one member from the object. I’m pretty new to Knockout and to Bootstrap, so I’m feeling pretty proud of myself at the moment.
Regarding callbacks (e.g., the parameter to the $.each() call in source()), I too hated the anonymous aspect of callbacks and always referred to my callback functions by name, defined elsewhere. But in an application of any substantial size, it just gets stupid trying to manage 100 two line callbacks, so I eventually just got over it. So I think “get over it” is a perfectly reasonable response. Life’s too short, right?
exelente!!!!
Great!
With your code I can fix duplicate itens…
source: function(query, process){
data = {}; // always clean before process.
//…
return process(data);
}
I don’t really like the fact that you’re using globals (map, states) in your example. It’s not just a matter of good practice, but you can actually get a lot of headaches if the page contains several typeahead controls.
Also, this approach forces you to use an anonymous function inside the “source” function, because you need to create a callback function for the Ajax call which in turn needs to call the typeahead callback function (called “process” in your example). I tend to avoid using anonymous functions for readability and clarity purposes.
So, this isn’t the solution I’m looking for yet… I know it’s easy to post criticism without an actual solution, so I will continue getting this to work myself and post an update soon! 🙂
Hi Mathieu,
Thanks for the comment, I appreciate it.
As far as using globals, your point is well taken. There are of course techniques to limit leakage, but there’s only so much you can do with JavaScript (it loves its globals).
As for using anonymous functions, I agree with the larger point, but not sure I fully understand the specific complaint here. The code inside
source()
is not anonymous andprocess()
is being passed in by Bootstrap (so there’s not much you can do about it).Either way, I’d love to see what you’ve come up with,
Thanks
Just two words mate, “THANK YOU”
Great post but for the life of me cannot get this to work correctly.
I have my JSON data returning as this:
{“COLUMNS”:[“USERNAME”,”ID”],”DATA”:[[“jclark”,”001650472″],[“jclark1″,”000086949”],[“jclarke”,”002386440″]]}
My type-ahead code is as follows:
$(function(){
var map = {};
var pages = [];
$(‘#add_user’).typeahead({
minLength: 3,
source: function ( query, process ) {
$.ajax({
url: ‘/glv/_includes/gl_data.cfc?method=search_accounts_by_username&returnformat=json’
,prefetch: ‘/glv/_includes/gl_data.cfc?method=search_accounts_by_username&returnformat=json’
,cache: false
,success: function(data){
map = {};
pages = [];
_.each( data, function(item, ix, list){
pages.push( item.username );
map[ item.username ] = item.id;
});
process( pages );
}
});
}
,matcher: function (item) {
if (item.toLowerCase().indexOf(this.query.trim().toLowerCase()) != -1) {
return true;
}
}
,sorter: function (items) {
return items.sort();
}
,highlighter: function (item) {
var regex = new RegExp( ‘(‘ + this.query + ‘)’, ‘gi’ );
return item.replace( regex, “$1” );
}
,updater: function ( selectedUsername ) {
$(‘#add_user’).val( map[ selectedUsername ] );
return window.location.href = $(selectedUsername).attr(“username”);
}
});
});
My input is never updated with matching accounts. What am I missing?
I’ve spent 2 + days on this, any HELP is appreciated.
THANK YOU
Thanks for your post, it helps 🙂
Thanks for writing this up. Definitely helped!
How to bootstrap typehead from Mysql?
Thank you so much for this simple yet very complete explanation. It was really usefull!
please tell me how i create a autosuggest textbox value reterive from database with the help of json please tell me
hi while working with array is working with absolutely fine in my yii applicaiton but while want to use with database its not working and since a week im finding code for how to get work with typeahead with yii.suggest me if any idea or related topic you have.
thanks this is really awesome
With Twitter Bootstrap 3 the typeahead plugin had been dropped, but you can still use Bootstrap 3 Typeahead (https://github.com/bassjobsen/Bootstrap-3-Typeahead/)
I Got Data[0] is undefined error , i am using same example , please suggest me if any thing is missing
@Dave : you are probably using this typeahead : https://github.com/twitter/typeahead.js
Replace [ states.push(state.stateName); ] by [ states.push({ value:state.stateName }); ]
I hope this will help…
Cédric
is it possible to use this method with bloodhound.js?
Nice tutorial, I was trying your code and then i figure it out that it could be much simpler
In de source method just surround the stateName in a span tag and give stateCode as attribute eg. data-state-code=”code”. In the updater method just use the jquery selector, so you can retrieve the code and the name
source: function (query, proccess) {
var results = new Array();
$.each(states, function(index, state) {
results.push(” + state.name + ”);
});
proccess(results);
},
updater: function (item) {
var $item = $(item);
// retrieve id|code for your benefits
var code = $item.data(‘state-code’);
…
…
return $item.text();
}
span html tags are not allowed :(… Then in this way:
source: function (query, proccess) {
….var results = new Array();
….$.each(states, function(index, state) {
….results.push(‘span data-state-code=”‘+state-code+'”‘ + state.name + ‘/span’); });
….proccess(results);
},
updater: function (item) {
….var $item = $(item);
….// retrieve id|code for your benefits
….var code = $item.data(‘state-code’);
….alert(code);
….return $item.text();
}
[…] File Name : How to use json objects with twitter bootstrap typeahead Source : tatiyants.com Download : How to use json objects with twitter bootstrap typeahead […]
[…] How to use json objects with twitter bootstrap typeahead […]