pquest
pquest

Reputation: 3290

Updating an observable on key press and click event

I have a value binding that looks like this:

<textarea class="form-control" placeholder="Comments" rows="10" data-bind="value: $root.GetTabComment($data).Comment, valueUpdate: 'keyup'"></textarea>

The reason I use keyup, is because I have a "save as you type" system set up. This works great as the user is typing, but if they correct spelling through spell check (using mouse clicks and no keyboard at all), the binding will not update.

The bound variable Comment is declared as:

Comment = ko.observable("").extend({throttle: 1000})

And the subscription is simply:

Comment.subscribe(function(){
  //save code
});

Is there some way for me to force the binding to take on the current value of the text area when a button is clicked?

Upvotes: 3

Views: 4376

Answers (2)

Simon_Weaver
Simon_Weaver

Reputation: 145880

textInput is far better for 'save as you type'

You just need to replace value: with textInput:

It handles browser differences much better.

http://knockoutjs.com/documentation/textinput-binding.html

Upvotes: 3

Tanner
Tanner

Reputation: 22733

Instead of using keyup you can try using input:

valueUpdate: 'input'

KnockoutJS - The "value" binding:

"input" - updates your view model when the value of an <input> or <textarea> element changes. Note that this event is only raised by reasonably modern browsers (e.g., IE 9+).

Here's a sample JSFiddle (originally authored by Michael Best) that I found and adapted that illustrates it's usage, where it handles both key strokes and mouse clicks along with throttling:

Demo JSFiddle

HTML:

<p>Type stuff here: 
    <input data-bind='value: instantaneousValue, valueUpdate: "input"' /></p>

<p>Current throttled value: <b data-bind='text: throttledValue'> </b></p>

<div data-bind="visible: loggedValues().length > 0">
    <h3>Stuff you have typed:</h3>
    <ul data-bind="foreach: loggedValues">
        <li data-bind="text: $data"></li>
    </ul>
</div>

JS:

function AppViewModel() {
    this.instantaneousValue = ko.observable();
    this.throttledValue = ko.computed(this.instantaneousValue)
                            .extend({ throttle: 400 });

    // Keep a log of the throttled values
    this.loggedValues = ko.observableArray([]);
    this.throttledValue.subscribe(function (val) {
        if (val !== '')
            this.loggedValues.push(val);
    }, this);
}

ko.applyBindings(new AppViewModel());

Upvotes: 6

Related Questions