I have a list of text boxes bound to the ko.observableArray
.
I have to make sure that text box values can't be blank, and I do it with jQuery by setting the value to 0 if it's blank on blur()
The problem is that the value change done with jQuery is not registered by knockout.
How do I observe the value change in my model?
See my simplified fiddle to get the point across - http://jsfiddle.net/k45gd/1/
HTML
<input type="number" data-bind="value: age" />
<span data-bind="text: age"></span>
<button data-bind="click: setAgeExternally">I want the label to change to 0</button>
JS
var model = function() {
this.age = ko.observable(21);
//this code is outside of the model, this is oversimplification
this.setAgeExternally = function(){
$('input').val(0);
}
};
ko.applyBindings(new model());
You need two things:
After changing the value of the element with jQuery, you need to let Knockout know to update the model. You can do this by triggering an
change
event:For Knockout (prior to 3.1.0) to respond to jQuery events, it needs to know that you're using jQuery. For that to happen, you must include jQuery in your document before Knockout.
Here's your fiddle with both updates: http://jsfiddle.net/mbest/k45gd/2/
In the example you provide, you're updating the input box with this code:
Considering that the input is bound to the age property, it would be simpler to do this:
However, even that isn't really needed, as the age property is exposed on your viewmodel. So external code could just do this, and the setAgeExternally method isn't really needed:
Let's jump back to your original problem - the one you describe but don't post code for. You mention that you have a list of input boxes bound to an observable array.
There is an interesting gotcha you need to be aware of when working with an observable array:
From the documentation at http://knockoutjs.com/documentation/observableArrays.html:
Given the requirements you list, there isn't any need for jQuery at all. You can try this three-part solution:
Make your observableArray contain observables. So you'd end up with something like:
Next, create a knockout extender that resets to 0 automatically if blank
Apply the extender to the observables in your array
Working fiddle: http://jsfiddle.net/tlarson/GF3Xe/
Used Michael Best suggestion:
This is the code that worked for me:
Thx MB, saved my time... :)