I am making an application using knockout + typeahead that will show suggestion list of entered character matches the list.
All thing working fine. Only problem is when I select the item from list it stores the whole object.
I want to store only name is first textbox and as per it store related value in second textbox.
I am not getting how to do that ?
can do using subscribe ? put subscribe on first textbox, it will get whole object then it will process the object then store values in related textbox.
HTML :
<input type="text" class="form-control" data-bind="typeahead: data, dataSource: categories"/> *
<input type="text" class="form-control" data-bind="value: item"/>
Java Script :
var ViewModel = function () {
var self = this;
self.categories = [
{ name: 'Fruit', items: 'abc' },
{ name: 'Vegetables', items: 'xyz' }
];
self.data = ko.observable();
self.item = ko.observable();
};
var viewModel = new ViewModel();
ko.bindingHandlers.typeahead = {
init: function (element, valueAccessor, allBindingsAccessor) {
var $e = $(element);
var accessor = valueAccessor();
var source = allBindingsAccessor().dataSource || [];
var names = new Bloodhound({
datumTokenizer: function (d) {
return Bloodhound.tokenizers.whitespace(d.name);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: source
});
names.initialize();
var substringMatcher = function() {
return function findMatches(q, cb) {
var matches, substrRegex;
substrRegex = new RegExp(q, 'i');
$.each(source, function(i, p) {
if (substrRegex.test(p.name)) {
matches.push({ value: p });
}
});
console.dir(matches);
cb(matches);
};
};
$e.typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'name',
displayKey: 'name',
source: names.ttAdapter()
}).on('typeahead:selected', function (el, datum) {
console.dir(datum);
accessor(datum);
}).on('typeahead:autocompleted', function (el, datum) {
console.dir(datum);
console.log(accessor);
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
console.log(value);
$(element).val(ko.utils.unwrapObservable(valueAccessor()));
}
};
ko.applyBindings(viewModel);
Here is jsfiddle of it.
I have asked question in morning also but i don't get answer so I code myself by studying the tutorials, but now I am stuck Here.
Any Suggestion on this situation ??
There are certain limitations with the temporary workout like knockout extension for Bootstrap Typeahead. I used it before in my project but it lead to a lot of limitations like custom control over templating, custom control over selected object property and selected object value. So I moved on to plugin jqAuto
which is based on JQuery-UI
autocomplete.
This plugin has enormous range of customizations and is faster than typeahead. I replicated your code in the jqAuto code and it is faster and cleaner than bootstrap typeahead.
JavaScript
var ViewModel = function() {
self.categories = [
{ name: 'Fruit', items: 'abc' },
{ name: 'Vegetables', items: 'xyz' }
];
self.data = ko.observable("");
self.item = ko.observable();
};
ko.applyBindings(new ViewModel());
HTML
<input data-bind="jqAuto: { source: categories, value: data, dataValue : data, inputProp: 'name', valueProp: 'name', labelProp: 'name' }" />
You can control the label propery, input property as well as value property in granular level.
Fiddle demo : http://jsfiddle.net/rahulrulez/uGGb8/4/
Detailed documentation of jqAuto plugin is given here : https://github.com/rniemeyer/knockout-jqAutocomplete