Parth Savadiya
Parth Savadiya

Reputation: 1211

Radio button does not change after ajax call (knockout js)

I am trying to edit user data but when I click on user id, radio button is not selected as per it's value.

result.IsActive returns true or false. I also try to set result.IsActive(true) by default in ajax response but it does't work. Where I am going wrong? Thanks in Advance

var self = this;
        self.DealerId = ko.observable();
        self.DealerName = ko.observable();
        self.Gender = ko.observable();
        self.Dealers = ko.observableArray(vm.Dealers());

          $.ajax({
                url: '@Url.Action("EditDealer", "Dealer")',
                cache: false,
                type: 'GET',
                contentType: 'application/json',
                data: { 'id': id },
                success: function (result) {
                    self.DealerId(result.DealerId);
                    self.DealerName(result.DealerName);
                    self.IsActive = ko.observable(result.IsActive);
                    $('#basic').modal('show');
                }
            });
<div class="modal fade" id="basic" tabindex="-1" role="basic" aria-hidden="true">
	<div class="modal-dialog">
		<div class="modal-content">
			<div class="modal-header" style="background-color:#4d90fe;padding-top:10px;padding-bottom:10px">
				<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
				<h4 class="modal-title" style="color:white">Update Dealer Information</h4>
			</div>
			<div class="modal-body">
                <div class="row">
                    <div class="col-md-12">
                        <div class="form-group">
                            <label class="control-label col-md-3">Dealer Name</label>
                            <div class="col-md-9">
                                <input class="form-control" data-bind="value:DealerName" required="required" 
                                    data-parsley-required-message="Dealer name is required"></input>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="row" style="margin-top:10px">
                    <div class="col-md-12">
                        <div class="form-group">
                            <label class="control-label col-md-3">Dealer Status</label>
                            <div class="col-md-9">
                                <label style="padding-left:0"><input type="radio" name="status" value="true" data-bind="checked: IsActive">Active</label>
                                <label ><input type="radio" name="status" value="false" data-bind="checked: IsActive">Inactive</label>
                            </div>                            
                        </div>
                    </div>
                </div>
			</div>
			<div class="modal-footer" style="margin-top:0;padding-top:10px;padding-bottom:10px">
				<button type="button" id="cancelSave" class="btn default" data-dismiss="modal" >Cancel</button>
				<button type="button" id="save" class="btn blue">Save</button>
			</div>
		</div>
	</div>
</div>

Upvotes: 0

Views: 417

Answers (2)

n.prokhorov
n.prokhorov

Reputation: 930

It seems, like you are initializing the property self.IsActive of your ko-viewmodel in ajax-success callback. That means, that your observable IsActive property will be created only when ajax is completed. But ajax call is asynchronous. So, if you are binding the viewmodel without the instantiated self.IsActive property you will got an error from ko. (check the browsers console). Its not a good way to make ajax-calls in viewmodel constructor.

Try to declare the property before the ajax like this:

var self = this;
    self.DealerId = ko.observable();
    self.DealerName = ko.observable();
    self.Gender = ko.observable();
    self.Dealers = ko.observableArray(vm.Dealers());
    self.IsActive = ko.observable(false);

      $.ajax({
            url: '@Url.Action("EditDealer", "Dealer")',
            cache: false,
            type: 'GET',
            contentType: 'application/json',
            data: { 'id': id },
            success: function (result) {
                self.DealerId(result.DealerId);
                self.DealerName(result.DealerName);
                self.IsActive(result.IsActive);
                $('#basic').modal('show');
            }
        });

In this case your radio will have default checked-value (be inactive), until the ajax completes. Right after ajax completes it will become the correct value. The best way to avoid this temporally data-inconsistence, is to load all the data before the viewmodel is created and pass all ajax-data as constructor argument. This approach grants, that ko-viewmodel will have actual data in the moment of binding. (something like this:

$.ajax({
            url: '@Url.Action("EditDealer", "Dealer")',
            cache: false,
            type: 'GET',
            contentType: 'application/json',
            data: { 'id': id },
            success: function (result) {
                //create your viewmodel inside the ajax-succcess and  
                //populate it with data
                var myViewModel = new MyViewModel(result);
                 //and apply ko-binding here, after creating the viemodel
                $('#basic').modal('show');
            }
        });
function MyViewModel(ajaxData){
 var self = this;
    self.DealerId = ko.observable(ajaxData.DealerId);
    self.DealerName = ko.observable(ajaxData.DealerId);
    self.Gender = ko.observable(ajaxData.DealerName);
    self.IsActive = ko.observable(ajaxData.IsActive);
    self.Dealers = ko.observableArray(vm.Dealers());
}

Upvotes: 2

Max Filippov
Max Filippov

Reputation: 2072

You need to assign equal name to both your <input type="radio"> to let the browser understand that they are related.

Upvotes: 0

Related Questions