9

The 1-way binding for the names + checkbox works fine, but it does not work initially for the radio button employeeTypeA although its value is true in the viewmodel the html shows the radio button as not set, why is that?

   <script type="text/javascript">

        $(function()
        {
            var PersonViewModel = function()
            {
                this.firstName = ko.observable('Lisa');
                this.lastName = ko.observable('T');
                this.isCustomer = ko.observable(true);
                this.employeeTypeA = ko.observable(true);
                this.employeeTypeB = ko.observable(false);
            };

            var personViewModel = new PersonViewModel();
            ko.applyBindings(personViewModel, $('data').get(0));
        });
    </script>

    <div id="data">
        <span data-bind="text: firstName"></span>
        <span data-bind="text: lastName"></span>
        <input type="checkbox" data-bind="checked: isCustomer" title="Is a customer" />
        <input name="x" type="radio" data-bind="checked: employeeTypeA" title="Employee type A" />
        <input name="x" type="radio" data-bind="checked: employeeTypeB" title="Employee type B" />
    </div>
Elisabeth
  • 18,252
  • 48
  • 179
  • 303

1 Answers1

9

The checked binding works differently for radio buttons, from the documentation:

For radio buttons, KO will set the element to be checked if and only if the parameter value equals the radio button node’s value attribute.

So you need to change your PersonViewModel to something like this:

var PersonViewModel = function()
{
    this.firstName = ko.observable('Lisa');
    this.lastName = ko.observable('T');
    this.isCustomer = ko.observable(true);
    this.employeeType = ko.observable('TypeB');                
};

And your radio buttons:

<input name="x" type="radio" data-bind="checked: employeeType" 
       value="TypeA" title="Employee type A" />
<input name="x" type="radio" data-bind="checked: employeeType" 
       value="TypeB" title="Employee type B" />

Demo JSFiddle.

If you want to keep the employeeTypeA and employeeTypeB properties you can introduce a computed property which returns the type:

this.employeeTypeA = ko.observable(false);
this.employeeTypeB = ko.observable(true);
this.employeeType = ko.computed(function()
{
     if (this.employeeTypeA())
        return 'TypeA';
     if (this.employeeTypeB())
        return 'TypeB';
},this);  

Also in this case you need to add the value attributes on your radio buttons.

Demo JSFiddle.

nemesv
  • 133,215
  • 15
  • 395
  • 348
  • I checked the knockoutJS site and looked at the tutorial: wantsSpam: ko.observable(true), but I did not see that wantsSpam is bound to a visibility property... not the radio button directly. As you also know about ASP.NET MVC would it not be a better idea to consider this Boolean to String 'Converter' in the server side viewmodel whatever that looks like?! – Elisabeth Apr 06 '13 at 19:53
  • When I put your last code block into my visual studio html file I get 2 errors/warnings: suspicious use this operator and not all code path return a value. – Elisabeth Apr 06 '13 at 20:02
  • Another question I have is why do you have the made this: "this.employeeTypeA()" and not "this.employeeTypeA". As far my javascript beginner knowledge goes employeeType is a property BUT you invoke like a function? This is no critic just a curious question :) – Elisabeth Apr 06 '13 at 20:18
  • To answer your questions: 1. How to wire this with ASP.NET MVC is completely different question, you should ask it in separete question. 2. Regarding the warnings: a `return ''` is missing at the end of computed. suspicious use `this`: it will work in this case but there are multiple ways to handle it like introducing a [`self` local reference to `this`](http://stackoverflow.com/questions/962033/) etc. 3. Regarding the "this.employeeTypeA()" call: `ko.observable` returns a function so `employeeTypeA` is a function and you need to call it with "this.employeeTypeA()" to get its value. – nemesv Apr 06 '13 at 20:22
  • ok thanks sounds good. I have seen samples using var self = this; Seems people are really using it differently browsing google. About 3.) It works also without the () ... :P 1.) ok will do a new question. – Elisabeth Apr 06 '13 at 21:47
  • Great... thanks for deciphering the docs for me :) I read it, guess I read it too fast. – Andrew Jun 08 '16 at 17:27