1

I have a series of input fields that are all bound to properties on an AngularJS model that are all editable.

Some of the fields are optionally calculated fields based on the other user input, a sample of the kind of input I'm working with can be found here.

Basically if someone enters a value in the time and distance it should automatically work out speed, or speed and distance will work out time, and so on.

1
  • You can use $watch to fire a callback whenever user changes time or distance and update other values accordingly. Commented Nov 29, 2013 at 12:46

2 Answers 2

5

The problem is underspecified since what if all the three values are specified by the user and he changes one of them? I took a guess and decided to change the last value which was touched by the user, keeping the recent two values constant.

I think it can be generalised for pretty much any formula, but your milage may vary. It was amusing to write. :)

Here is a working example: http://jsbin.com/OsuMaSek/1/edit

$scope.time = 0;
$scope.distance = 0;
$scope.speed = 0;

$scope.touchOrder = {
  speed: 0,
  distance: 0,
  time: 0
};

function getLastTouched() {
  var minTouched = null, minVal = Infinity;
  Object.keys($scope.touchOrder).forEach(function (k) {
    if (minVal > $scope.touchOrder[k]) {
      minVal = $scope.touchOrder[k];
      minTouched = k;
    }
  });
  return minTouched;
}

$scope.totalTouchCount = 0;
$scope.touched = function (valTouched) {
  $scope.totalTouchCount++;

  $scope.touchOrder[valTouched] = $scope.totalTouchCount;

  if ($scope.totalTouchCount >= 2) {
    switch(getLastTouched()) {
      case 'time': $scope.time = $scope.distance / $scope.speed; break;
      case 'distance': $scope.distance = $scope.time * $scope.speed; break;
      case 'speed': $scope.speed = $scope.distance / $scope.time; break;
    }
  }
};
Sign up to request clarification or add additional context in comments.

2 Comments

Yeah I can see monitoring the change being an ideal way to track it. And I do realise that if the user enters into all three fields strange things can happen, but it's likely that the user should enter speed or distance, not both (and if they do we override).
@Slace I think it is quite a nice model to allow user to enter any field but it works better when there are only two fields (unit conversion, for example) instead of three. With three fields, it is difficult to figure out which field does the user expect to update. If you fix time, it would work out nicely.
1

You can write something like that (by using $watch):

JS

angular.module('app', [])
.controller('Ctrl', function ($scope) {

  $scope.mymodel = {};

  $scope.mymodel.time = 0;
  $scope.mymodel.distance = 0;
  $scope.mymodel.speed = 0;


   $scope.$watch(function () {
    return $scope.mymodel;
},
function (newValue, oldValue) {
    $scope.mymodel.speed = (newValue.distance > 0) ? newValue.distance / newValue.time : 0;
}, true);

});

HTML

 Time: <input type="number" ng-model="mymodel.time" />
  <br />
  Distance: <input type="number" ng-model="mymodel.distance" />
  <br />
  Speed: <input type="number" ng-model="mymodel.speed" />

Comment

Its only example, in this case you can't change velocity (speed).

Changed DEMO

[EDIT]

you can play with $watch to control sub-fields:

$scope.$watch(function () {
    return $scope.mymodel;
},
function (newValue, oldValue) { 

  if(newValue.speed != oldValue.speed){   
    $scope.mymodel.time = newValue.distance / newValue.speed;
    $scope.mymodel.distance =newValue.time *newValue.speed;
  }
  else if(newValue.distance != oldValue.distance){   
       $scope.mymodel.speed = (newValue.distance > 0) ? newValue.distance / newValue.time : 0;
  }
   else if(newValue.time != oldValue.time){   
      $scope.mymodel.speed = (newValue.distance > 0) ? newValue.distance / newValue.time : 0;
  }


}, true);

Demo 2

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.