0

I can't make my two input fields update values when changing the opposite input.

What I want to do is make a basic $dollar to Gold oz calculator that takes in two input fields. Sample Preview: http://embed.plnkr.co/dw6xL95zRqJC1pIlE1Kf/preview

The first input is the dollar amount, the second an ounces amount. There is a third variable that contains the gold selling rate.

In my code I have been able to successfully changing the Dollar amount and make the oz amount update via angular two way data binding.

The problem is trying to make the opposite work; for example, changing the oz amount should also update the dollar amount.

Here is my html code:

<div class="row panel" ng-controller="ctrl">

  <!-- Dollar input -->
  <label class="small-6 columns">Dollar $:
    <input type="number" ng-model="dollar">
  </label>

  <!-- Ounces input -->
  <label class="small-6 columns">Ounces (oz):
    <input type="number" value="{{ ozCalc() | number:4 }}">
  </label>

</div>

Here is my angular code:

var app = angular.module('app', []);

app.controller('ctrl', ['$scope', function($scope) {
    $scope.dollar = 0;
    $scope.oz = 0;
    $scope.rate = 1267;

    //Dollar to Ounce Calculator
    $scope.ozCalc = function() {
        var oz = $scope.dollar / $scope.rate;
        return oz;
    };

    //Ounce to Dollar Calculator
    $scope.dollarCalc = function() {
        var dollar = $scope.oz * $scope.rate;
        return dollar;
    };

}]);

Any help would be really appreciated. Thanks

2 Answers 2

2

For one, you need to 2-way bind the oz input too:

<input type="number" ng-model="oz">

Then you need watches over the 2 models:

$scope.$watch('dollar', function(newval, oldval) {
    $scope.oz = ozCalc(newval);
});

$scope.$watch('oz', function(newval, oldval) {
    $scope.dollar = dollarCalc(newval);
});

With a small change in the functions (sidenote: consider refactoring them to a service):

//Dollar to Ounce Calculator
function ozCalc(dollar) {
    var oz = dollar / $scope.rate;
    return oz;
}

//Ounce to Dollar Calculator
function dollarCalc(oz) {
    var dollar = oz * $scope.rate;
    return dollar;
}

This does NOT trigger infinite digest cycles. See forked plunk: http://plnkr.co/edit/m3YLodjvmglLMlqSHtFi?p=preview

If you want the oz input to be formatted to 4 digits, use the ngModel.$parsers/$formatters pipelines, not a filter.

Sign up to request clarification or add additional context in comments.

Comments

0

Use something like ng-change. In html you would have something like

<div class="row panel" ng-controller="ctrl">

  <!-- Dollar input -->
  <label class="small-6 columns">Dollar $:
    <input type="number" ng-model="dollar" ng-change="update()">
  </label>

Adding in angular a function to update your oz

$scope.update = function() {
    // add logic here doing what ozCalc() is doing
    $scope.oz = updatedValue;
}

you will need to change your expression for a ng-model and do another ng-change.

  <!-- Ounces input -->
  <label class="small-6 columns">Ounces (oz):
    <input type="number" ng-model="oz" ng-change="update2()">
  </label>

</div>

Then add another function in angular

$scope.update2 = function() {
    // add logic here
    $scope.dollar = updatedValue;
}

Also, a note with useing ng-model correctly:

https://github.com/angular/angular.js/wiki/Understanding-Scopes

This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models

The take away on this is any model you use make sure to set it up so that you need to do something to the following.

<input type="number" ng-model="amount.oz">

in your code have something like this

$scope.amount = {
    oz = 0;
    dollar = 0;
}

If you don't use a . in your ng-model sometimes there will be a child node that will overwrite the parent node removing your ability to edit the actual variable. This is usually not a problem unless your using something like ng-repeat but I thought it is worth mentioning.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.