Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding true / false to radio buttons in Knockout JS

In my view model I have a IsMale value that has the value true or false.

In my UI I wish to bind it to the following radio buttons:

<label>Male    <input type="radio" name="IsMale" value="true" data-bind="checked:IsMale"/> </label>  <label>Female    <input type="radio" name="IsMale" value="false" data-bind="checked:IsMale"/> </label> 

The problem I think is checked expects a string "true" / "false". So my question is, how can I get this 2-way binding w/ this UI and model?

like image 273
C.J. Avatar asked Apr 12 '12 15:04

C.J.


People also ask

How to bind checkbox in Knockout?

You can add both a checked and click binding to an input. However, you would want to return true; from the click handler. This will allow the default action to proceed (the checkbox will be checked/unchecked).

What is two way binding in knockout JS?

KO is able to create a two-way binding if you use value to link a form element to an Observable property, so that the changes between them are exchanged among them. If you refer a simple property on ViewModel, KO will set the form element's initial state to property value.

Are radio buttons Boolean values?

Radio Button do not work for bool value.


2 Answers

I know this is an old thread, but I was having the same problem and found out a much better solution that was probably added to knockout after this question was officially answered, so I'll just leave it for people with the same problem.

Currently there is no need for extenders, custom binding handlers or computeds. Just provide a "checkedValue" option, it will use that instead of the html 'value' attribute, and with that you can pass any javascript value.

<input type="radio" name="a" data-bind="checked:IsChecked, checkedValue: true"/> <input type="radio" name="a" data-bind="checked:IsChecked, checkedValue: false"/> 

Or:

<input type="radio" name="b" data-bind="checked:Quantity, checkedValue: 1"/> <input type="radio" name="b" data-bind="checked:Quantity, checkedValue: 2"/> <input type="radio" name="b" data-bind="checked:Quantity, checkedValue: 3"/> 
like image 143
Natan Avatar answered Oct 11 '22 07:10

Natan


One option is to use a writeable computed observable.

In this case, I think that a nice option is to make the writeable computed observable a "sub-observable" of your IsMale observable. Your view model would look like:

var ViewModel = function() {    this.IsMale = ko.observable(true);     this.IsMale.ForEditing = ko.computed({         read: function() {             return this.IsMale().toString();           },         write: function(newValue) {              this.IsMale(newValue === "true");         },         owner: this             });           }; 

You would bind it in your UI like:

<label>Male    <input type="radio" name="IsMale" value="true" data-bind="checked:IsMale.ForEditing"/> </label>  <label>Female    <input type="radio" name="IsMale" value="false" data-bind="checked:IsMale.ForEditing"/> </label> 

Sample: http://jsfiddle.net/rniemeyer/Pjdse/

like image 37
RP Niemeyer Avatar answered Oct 11 '22 07:10

RP Niemeyer