I just can't get this to work after trying hours' worth of ideas.
Simple need: I have a textbox (INPUT type TEXT) and a Div tag:
<body>
<input id="tb" type="text"/>
<div id="Words" data-bind="text: WordCount"></div>
</body>
Ideally, all I want to do is update the WordCount each time the user types a new character into the tb text box.
In an effort to do that, I created a ViewModel:
function ViewModel() {
var self = this;
self.recalcFlag = ko.observable();
self.WordCount = ko.computed(function () {
self.recalcFlag();
return CountWords($("#tb").wijinputtext("option", "text"))
}, this);
self.recalcWordCount = function () {
self.recalcFlag.notifySubscribers();
}
}
The CountWords function I'm using looks like this:
function CountWords(inputString) {
var splitArray = inputString.split(" "), obj = {};
for (var x = 0; x < splitArray.length; x++) {
if (obj[splitArray[x]] === undefined) {
obj[splitArray[x]] = 1;
} else {
obj[splitArray[x]]++;
}
}
return splitArray.length;
}
The technique above is one I saw as a solution in another SO post--a way to get a computed ko value to refresh/update on-demand. The idea is to call recalcWordCount from a keypress function. But the problem is that my recalcWordCount function is inside my ViewModel object--and Knockout has already created an instance of that. I don't know how to get to ko's instance of the ViewModel in order to call the function. For example, this doesn't work:
<input id="tb" type="text" onkeypress="recalcWordCount();" />
Also, this doesn't work:
<input id="tb" type="text" onkeypress="ViewModel.recalcWordCount();" />
Also, this doesn't work:
<input id="tb" type="text" onkeypress="ko.viewModel.recalcWordCount();" />
I would appreciate any suggestion on how can I get this to work.
You can add an observable 'filter' and bind it with the input like this:
<input data-bind="value: filter, valueUpdate: 'afterkeydown'" />
and then use the observable in the computed 'WordCount'
self.WordCount = ko.computed(function () {
var filter = this.filter();
return CountWords(filter)
}, this);