1

I was looking for some assistance. I am very new to Angular, but I have searched and haven't been able to find an answer. The basic situation is that I have 5 input boxes. As these are changed the data in a table changes. However, I have a row of data that is dependent on the prior cell, so if A = 1, B = A + 2, C = B +1, etc. I would prefer not to repeat all the crazy math I have to get the number for cell A. I have tried adding ng-model to the html cells (which of course has no affect once the page is first initialized. Is there a way to bind a cell's contents to the prior cell's contents without having an input of some kind? Thanks!

Here is a sample of what I'm trying to do in code form:

<input type="text" ng-model="value1"><br>
<input type="text" ng-model="value2"><br>

<p ng-model="value3">{{value1 + value2}}</p>
<p>{{value 3 + value1}}</p>

This is a very simplified version, but the gist is there. (so no it isn't as simple as having the 2nd <p> be {{value3 + 2 * value1 + value2}})

Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106
MeanDean73
  • 145
  • 1
  • 3
  • 13
  • 1
    Calculate `value3` using `ng-change` on the first two inputs. – Jim Cote Feb 25 '15 at 16:19
  • Hi @JimCote, so in this situation imagine there are 10 more `

    `s, with the next one being dependent on the prior value. Would `ng-change` allow me to have say a value4 = value3 + value (heavily simplified), value5 = value4 + value1, etc?

    – MeanDean73 Feb 25 '15 at 16:32
  • 1
    Use an array `value[]` instead of `value1`, `value2`, etc. and `ng-repeat` with something like `ng-change="func($index)"`. – Jim Cote Feb 25 '15 at 16:40
  • @JimCote Good suggestion if the values don't have any particular meaning for naming: Something like that: http://stackoverflow.com/a/19432646/986160 – Michail Michailidis Feb 25 '15 at 16:41
  • Awesome! Would the `ng-change` be on the inputs, and `ng-repeat` on the html elements? – MeanDean73 Feb 25 '15 at 16:42
  • ng-repeat is when you don't know the number of inputs you have - Are you going to be adding more inputs dynamically (e.g pushing a button) ? Either way you can do a ranged repeat by piping the range like this: http://stackoverflow.com/a/11878038/986160 but you have to have a pattern for all the ng-change function attributes otherwise there is no way to do it with ng-repeat if you are not consistent – Michail Michailidis Feb 25 '15 at 16:51

1 Answers1

1

You could have a function that is called when ng-change on each of the inputs happens. You should avoid having logic/arithmetic in the view..

Then you can have this function in the controller of the page or element and call it like

<input type="text" ng-change="ctrl.myFunc(value1,value2)"/>

for both inputs.

Edit: By the way there is no ng-model for p tag!! you need to make that a readonly input instead if you want to use it for other subsequent value caluclation. http://docs.angularjs.org/api/ng/directive/ngModel

Edit 2: Alternatively you can use value="{{value1 + ... }}" in your inputs like (given your example):

<input type="text" ng-model="A" value="0"/>
<input type="text" ng-model="B" value="{{A + 2}}"/>
<input type="text" ng-model="C" value="{{B + 1}}"/>

Edit 3:

Here is the full solution: (also in plunkr to see it in action: http://plnkr.co/edit/FXAae6mjOGOfw2Xczlb1) Keep in mind that having everything in $scope is a bad practice for bigger applications and also <br/>'s shouldn't be used. This is an example just for illustration purposes :)

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example</title>


  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.0-beta.5/angular.min.js"></script>



</head>
<body ng-app="bindExample">
  <script>
  angular.module('bindExample', [])
    .controller('ExampleController', ['$scope', function($scope) {
      $scope.calculate = function() {
          if (!$scope.noninput) $scope.noninput = [];
          if (!$scope.value) $scope.value = [];
          $scope.noninput[0] =  parseInt($scope.value[0]) + parseInt($scope.value[1]) || 0;
          $scope.value[2] = $scope.noninput[0]+100;
      };
    }]);
</script>
<div ng-controller="ExampleController">
  1st Value  plus: <input type="text" ng-model="value[0]" value="{{value[0]}}" ng-change="calculate()"/><br/>
  2nd Value: <input type="text" ng-model="value[1]" value="{{value[1]}}" ng-change="calculate()"/><br/>
  Non input result: <span ng-bind="noninput[0]">{{noninput[0]}}</span><br/>
  Value 3nd (non-input result plus 100): <input type="text" ng-model="value[2]" value="{{value[2]}}"/><br/>
  <br/>
  Model:<br/>
  (Input Values): {{value}}<br/>
  (Non Input Values): {{noninput}}<br/>
</div>
</body>
</html>
Michail Michailidis
  • 11,792
  • 6
  • 63
  • 106
  • I actually am not having a whole lot of difficulty with the changing of the first `p`, since it is calculated based off the 2 (in this example) inputs. However, the 2nd `p`, which is dependent on the results of the 1st, is the one I need to worry about. Are you suggesting adding `ng-change` to the inputs, to create value 3, which I can then use in my calculations for the 2nd `p`? – MeanDean73 Feb 25 '15 at 16:28
  • yeah your function will manipulate value3 in the scope which is ng-model specified and whatever contains value3 will be updated accordingly. Note btw that having everything in the scope variable is generally a bad practice for bigger applications – Michail Michailidis Feb 25 '15 at 16:33
  • Again, I am super new to Angular, so what would you recommend instead of using the scope variable? – MeanDean73 Feb 25 '15 at 16:34
  • there is no ng-model for p!! you need to make that a readonly input https://docs.angularjs.org/api/ng/directive/ngModel – Michail Michailidis Feb 25 '15 at 16:34
  • in the future you will use directives with isolated scopes and services for passing things around but these are way complicated for you now :) one step at a time – Michail Michailidis Feb 25 '15 at 16:35
  • Yes, i understand p doesn't have ng-model, it is only inputs, selects, and textareas. It was really more of just an illustration of what I was trying to accomplish, with having html data dependent on other html data which in turn was dependent on input values. – MeanDean73 Feb 25 '15 at 16:36
  • Alternatively you can put value="{{value1 + ... }}" in your inputs – Michail Michailidis Feb 25 '15 at 16:38
  • The thing is, the inputs aren't dependent on one another. It is the non-inputs where I am displaying the calculated values based off those inputs where I need to use one (non-input) value to calculate the next. – MeanDean73 Feb 25 '15 at 17:05
  • well as I said you can replace p's with inputs make them readonly, change the mouse pointer, remove border and it will behave like

    . This way you can use ng-models everywhere. If you don't want to do that you have to introduce new variables in your model (i.e on scope var) and have ng-change just for inputs. The ng-change will be calling a function called recalculate and do all the calculations there..

    – Michail Michailidis Feb 25 '15 at 17:38
  • Got it to work. Thanks for putting me on the right path! I did what you said, created variables in the $scope, and then had them change on an input change, and then referenced them in the html fields by referencing these variables. Thanks again! – MeanDean73 Feb 25 '15 at 17:55
  • @MeanDean73 Thanks for accepting the answer! Check the full solution I just added with a plunkr if you don't want to use inputs as I said.. – Michail Michailidis Feb 25 '15 at 18:07