Question

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.

Was it helpful?

Solution

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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top