I'm using the Bootstrap Typeahead plugin like so:
$('#Organisation').typeahead({
source: function (query, process) {
return $.get(AppURL + 'Organisations/Manage/SearchByName/',
{
term: query
},
function (data) {
var results = [];
var fullResults = [];
$.each(data, function (index, item) {
results.push(item.label);
fullResults.push({
id: item.ID,
label: item.label
});
});
return process(results);
});
},
updater: function (selection) {
$('#OrganisationID').val(selection);
}
});
I have two returned arrays, this is because Typeahead ONLY wants a list of strings instead of an object. The second array contains both the label and id.
Once a user selects an item from the list I need to get the ID from this selection and then use it to insert into a hidden field. But the selection will just be the name, as the ID can't be passed through via Typeahead.
Any ideas on how I can solve this?
An example of the two returned arrays:
results: ["Organisation 1","Organisation 2"]
fullResults: [{"label":"Organisation 1","ID":2},{"label":"Organisation 2","ID":1}]
After searching around a bit on the net I found this HowTo. In it they do what you want, but with no ajax.
You should also be able to return a object, from the source function, but you would need to re-implement all the helper functions of typeahead.
You cannot normally use JSON objects directly within Bootstrap Typeahead (2.x), but you can easily tweak it to do so. The wording of this question should help for people to find this in one place. Other questions have asked similar things, but not identical to the way that you did.
var typeahead = control.typeahead({ /* ... */ }).data('typeahead');
// manually override select and render
// (change attr('data-value' ...) to data('value' ...))
// otherwise both functions are exact copies
typeahead.select = function() {
var val = this.$menu.find('.active').data('value')
this.$element.val(this.updater(val)).change()
return this.hide()
};
typeahead.render = function(items) {
var that = this
items = $(items).map(function (i, item) {
i = $(that.options.item).data('value', item)
i.find('a').html(that.highlighter(item))
return i[0]
});
items.first().addClass('active')
this.$menu.html(items)
return this
};
Other than that, you must override highlighter
, matcher
, sorter
, and updater
, but those can done via the options passed into the typeahead, where the passed in item
(s) are now your JSON objects.
When selecting item
s, updater
is called, which is how you set the value and use the JSON data:
updater: function (item) {
someGlobalValue = item.id;
// must return a normal string; sets the textbox value
return item.name;
}
This also means that you don't need to do anything fancy to associate, or otherwise "remember" the items external to Typeahead referenced example in the other answer. The most annoying part of the whole overriding process is rewriting the sorter
in every use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With