As per this other stackoverflow answer:
knockout event binding
and summarised as:
Allowing the default action
By default, Knockout will prevent the event from taking any default
action. For example if you use the event binding to capture the
keypress event of an input tag, the browser will only call your
handler function and will not add the value of the key to the input
element’s value. A more common example is using the click binding,
which internally uses this binding, where your handler function will
be called, but the browser will not navigate to the link’s href. This
is a useful default because when you use the click binding, it’s
normally because you’re using the link as part of a UI that
manipulates your view model, not as a regular hyperlink to another web
page.
However, if you do want to let the default action proceed, just return
true from your event handler function.
So the default is that unless you return true, the default event will be prevented.
If it's checked value you want to control you could the following, it's a bit long winded mind you and a definite hack, but it works.
Setup an observable on your viewmodel to hold whether the checkbox is checked or not
self.isChecked = ko.observable(false);
Setup a computed observable on your vm that will be used to bind to the checkbox checked value;
self.isCheckedCp = ko.computed(function(){
return self.isChecked();
});
Bind the computed to the checked attribute in the html:
<input type="checkbox" id="thisFails" data-bind="click: $root.Fails,checked:isCheckedCp" />
Change the Fails function to incorporate a timeout that will run immediately after the fails function completes, and in that function, set the value of the underlying isChecked observable (in the example it just toggles the current value)
self.Fails = function(e) {
console.log('e',e.isChecked());
alert('arse');
console.log( $('#thisFails'));
setTimeout(function(){
console.log('set now');
//this works
self.isChecked(!self.isChecked());
//still doesn't work with the set timeout
$('#thisFails').attr('checked', true);
console.log('e',e.isChecked());
}, 0);
}
If you step through the execution of it, you will see that the when it gets to the setTimeout console.log('set now'); that the checkbox has reverted to what it was when you clicked it.
Setting the self.isChecked then updates the observable and the computed is accessed and the checkbox display is updated.
Now the reason that works is quite a bit beyond my knowledge of browsers and their execution paths, but I think the setTimeout with the zero timeout value effectively adds this bit of code to run immediately after the current (click in this case) function, this link goes into some detail:
Why is setTimeout(fn, 0) sometimes useful?
I can't work out why setting checked attribute via your original jquery doesn't work when tried in that timeout function though.
I hope this actually helps you somehow!