SrinivasNaidu
SrinivasNaidu

Reputation: 519

Radio button observable value is not changing in knockout js

I have a object Address. In address there are fields like street, country,state,IsDefault. The addresses can be multiple and IsDefault will be radio button.

   $.each(self.Addresses(), function (index, address) {  
        address.Street = ko.observable(adderss.Street);         
        address.State = ko.observable(address.State);
        address.Country = ko.observable(address.Country);
        address.IsDefault = ko.observable(address.IsDefault.toString());
        address.IsGlobalCheckbox = ko.computed({
            read: function () {
                return address.IsDefault() + "";
            },
            write: function (v) {                   
                if (v == "true") {
                    address.IsDefault(true)
                }
                else {
                    address.IsDefault(false)
                }
            }
        });
    });

The Html content will be

    <div data-bind="foreach: Addresses">
<div>
    Address <span data-bind="text: ($index() + 1)" class="mrl"></span>


    <input name="contactAddress" type="radio" data-bind="checked:IsGlobalCheckbox,attr: { value:IsDefault }" />

    <span>Primary</span>



<div data-bind="attr:{id:'address'+($index() + 1)}" class="in">
    <div class="row">            
        <div class="form-group">
            <label>Street 1</label>
            <input type="text" data-bind="value: Street" />
        </div>
    </div>
    <div>           
        <div class="form-group medium">
            <label >Country</label>
            <input data-bind="value:Country" />
        </div>
        <div class="form-group medium">
            <label>State</label>
            <input type="text" data-bind="value:State" />
        </div>
    </div>
</div>

When i am changing one default address then it is changing, but remaining is default observables are not changing. Hope you understand my question.

I am attaching a fiddle explaining my requirement in the fiddle http://jsfiddle.net/Naidu526/fzX8C/2/

In that fiddle when i am changing the IsDefault from one field to another field the other observable value is not changing. Please check the json format that is displayed below

Upvotes: 0

Views: 1337

Answers (1)

Origineil
Origineil

Reputation: 3118

The problem is that you are never clearing/falsifying the state from the previously selected Address nor do you have access to that value.

Using and duplicating (see IsGlobalCheckbox) the value of IsDefault within each Address doesn't make much sense. If only 1 can be selected and that state is to be communicated to all others, then that context belongs above/outside of the Address model. Even the current naming indicates it doesn't belong there.

So, define a new observable in $root/$parent depending on the overall structure of the production model to store the Primary Address.

 self.primaryAddress = ko.observable();

Change the html binding to use the checkValue parameter of the checked binding so that the actual Address is stored in the model.

 <input name="contactAddress" type="radio" data-bind="checked:$root.primaryAddress, checkedValue: $data" /> <span>Primary</span>

Now we have the proper setup to "listen" for changes and modify IsDefault accordingly.

Two options are available:

  1. Manage the value manually via 2 subscriptions on primaryAddress
  2. Turn IsDefault into a computed observable with a dependency on primaryAddress

I like option #2.

address.IsDefault = ko.computed(function(){
  return address === self.primaryAddress()
});

Just be sure to include the initialization:

 if(address.IsDefault == "true"){          
   self.primaryAddress(address)
 }

See my fiddle for the full setup. I have also included Option #1 in commented-out code just as a reference.

Upvotes: 1

Related Questions