Joe82 Joe82 - 5 months ago 115
AngularJS Question

AngularJS - Ng-change updating value but not toggling radio button

I have two input options that are linked via ng-model in order to display always the same country in both places.

<select ng-model="selectedCountry" ng-options="country.name for country in countries">
<select ng-model="selectedCountry" ng-options="country.name for country in countries">


Each country has different shipping costs, and once the country is selected you can also choose between different shipping options ("normal" and "express" with a radio button. I want to make it always display the "normal" cost when switching the country, and I made it by adding a ng-click to each of the input options and adding a ng-change in order to listen to the changes:

<select ng-model="selectedCountry" ng-options="country.name for country in countries" ng-change="changeShipping()" ng-click="shippingPrice=selectedCountry.shipping.normal">


The problem is that while the data shown in the view is the correct when changing the country, but the radio button is still set in the wrong option.
This is my controller logic:

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.countries = [{
"name": "Freedonia",
"shipping" :
{
"normal":30,
"express":70
}
},{
"name": "Mordor",
"shipping" :
{
"normal":70,
"express":110
}
},{
"name": "Oz",
"shipping" :
{
"normal":140,
"express":180
}
}];

$scope.selectedCountry = $scope.countries[0];

$scope.changeShipping = function() {
return $scope.shippingPrice = $scope.selectedCountry.shipping.normal;
};
});


You can see a working fiddle here Thanks in advance!

Answer

Use ng-model with input[radio] and set it's value on select change.

UPDATED JSFIDDLE

var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
    $scope.shippingType = 'normal';	// initial value for input[radio]

    $scope.countries = [{
        "name": "Freedonia",
        "shipping": {
            "normal": 30,
            "express": 70
        }
    }, {
        "name": "Mordor",
        "shipping": {
            "normal": 70,
            "express": 110
        }
    }, {
        "name": "Oz",
        "shipping": {
            "normal": 140,
            "express": 180
        }
    }];

    $scope.selectedCountry = $scope.countries[0];

    $scope.changeShipping = function () {
        $scope.shippingType = 'normal';    // set back to normal on country change
        return $scope.shippingPrice = $scope.selectedCountry.shipping.normal;
    };
});
.summary{
  background-color:gray;
  border:1px solid black;
  font-family:Arial;
  margin-bottom:52px;
  color:white;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-controller="myCtrl" ng-app="myApp">
  <div class="summary">
  Summary:<br>
  Country:<select ng-model="selectedCountry" ng-options="country.name for country in countries" ng-change="changeShipping()">
    </select><br>
  Shipping Costs: 
    {{selectedCountry.shipping[shippingType]}}
  </div>
  <div>
    <select ng-model="selectedCountry" ng-options="country.name for country in countries" ng-change="changeShipping()">
    </select>
  </div>
  
  Shipping costs:
  <form>
    <input type="radio" name="shippingOptions" value="normal" ng-model="shippingType">
    Normal {{selectedCountry.shipping.normal}}<br>
    <input type="radio" name="shippingOptions" value="express" ng-model="shippingType">
    Express {{selectedCountry.shipping.express}}<br>
  </form>
</div>

Comments