Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout.Js doesn't detect programmatically changed checkbox state

I have a simple checkbox which has its value adjusted by a bit of infrastructure that I'm writing to persist state in localStorage. I am aware that this would normally be done by setting the viewModel but the infrastructure is unaware of any knockout bindings and has no access to them.

I didn't think this would be a problem as I assumed that knockout was running off the 'change' event, however $checkbox.prop('checked', true).trigger('checked') fails to trigger my observable. Even using the click event directly doesn't get me quite what I need.

What events does knockout wire to? How do I get it to read the state of the control?

jsbin showing this weird behavior here. Try selecting the checkbox directly versus clicking the button.

like image 753
George Mauer Avatar asked Jan 03 '13 16:01

George Mauer


3 Answers

I found a better way of doing that. Just put this code inside of your domready event:

    $("input:checkbox").bind('change', function () {
        $(this).triggerHandler('click');
    });
like image 174
Roman Pushkin Avatar answered Nov 15 '22 21:11

Roman Pushkin


Knockout bindings don't really work in the way you are thinking.

Check out: http://knockoutjs.com/documentation/custom-bindings.html

Here is one solution you can use, no jQuery, no custom binding.

Your html will stay the same.

var m = {
  isChecked: ko.observable(false),
  infrastructureUpdatesCheckbox: function() {
    this.isChecked( this.isChecked() === true ? false : true);
  }
};

ko.applyBindings(m);
like image 34
Jack Avatar answered Nov 15 '22 20:11

Jack


you should change checkbox' checked status via your view model:

 var m = {
   isChecked: ko.observable(false)
  //,infrastructureUpdatesCheckbox: function() {
    //$chk = $(':checkbox');
    //$chk
    //  .prop('checked', !$chk.prop('checked'))
    //  .trigger('change');
    //this.isChecked(!this.isChecked());  // this - is your view model
 }
};

here is updated version:

function InfrastructureUpdatesCheckbox(){

  var $cb = $(':checkbox');
  var cb = $cb[0];
  cb.checked = !cb.checked;  // manually change checked status
  $cb.triggerHandler('click');  // run all event handlers bound to 'click' event
}

I guess the issue is related to checkboxes (radio buttons) only. Other controls should behaive correctly when you trigger events manually.

like image 1
Rustam Avatar answered Nov 15 '22 19:11

Rustam