Reputation: 51
To change the status of a checkbox with javascript doesn't correspond to the spirit of MVVM. But I'm creating a general javascript library for better looking standard controls like checkbox, radio button or selectbox. Based on the following viewmodel:
function MyViewModel() {
var self = this;
self.ok = ko.observable();
};
var vm = new MyViewModel();
ko.applyBindings(vm);
But I get a problem in conjunction with knockout when I change the checked status of a checkbox programmatically:
document.getElementById('chk').checked = true
The change will not appear in the property of the viewmodel. But when I click the checkbox all works fine.
Look at http://jsfiddle.net/KWdZB/1/
Is there any workaround?
Upvotes: 3
Views: 1371
Reputation: 684
This is normal because the checked binding handlers doesn't subscribe to the checked change event but subscribe to the click event handler (You can see on source file at the checked binding handlers code).
If you need to change value with click, you must to do with the ok observable value.
There is the HTML
<div>
<input type="checkbox" id="chk" data-bind="checked: ok"/><br>
<input type="button" id="btnCheck" value="Check" data-bind="click: Check"/>
<input type="button" id="btnUnCheck" value="Uncheck" data-bind="click:Uncheck"/>
</div>
<div>
Value: <span data-bind="text: ok"></span>
</div>
And the javascript :
function MyViewModel() {
var self = this;
self.ok = ko.observable();
self.Check = function(){
self.ok(true);
}
self.Uncheck = function(){
self.ok(false);
}
};
vm = new MyViewModel();
ko.applyBindings(vm);
You can see it in this fiddle.
Upvotes: 1
Reputation: 139798
Your problem is that ko subscribes on the click
event inside the checked binding:
ko.utils.registerEventHandler(element, "click", updateHandler);
But changing the checked
attribute won't trigger the click event so ko won't be notified.
If you manually trigger the click event after the attribute change it can work...
I don't know how to do it with pure javascript but with jQuery you can write:
$('#chk').attr('checked', true).triggerHandler('click')
You can test it in this JSFiddle
.
Upvotes: 5