warmwhisky
warmwhisky

Reputation: 489

Angular Why doesn't watch work and should I even be using it?

I am trying to get the value of some inputs that rely on data from other inputs. I believe I need a watch to achieve this, but I am not sure because everything I have tried fails with errors I have no idea how to deal with.

I have a wholesale order form with five fields on multiple rows e.g.

code | quantity | price | discount % | total 1 |
code | quantity | price | discount % | total 2 |
code | quantity | price | discount % | total 3 |
code | quantity | price | discount % | total 4 |

Code column is an autocomplete list of product codes that when clicked fill the price column. Then when quantity and discount are adjusted the total column is updated.

Total is purely display for the user, but is instantly updated when either of the 3 previous inputs are changed. I am trying to get a running total of all totals displayed for the user. Here are some of my attempts to watch the the totals.

Here is a plunker http://embed.plnkr.co/XdGjHy

Here are my inputs. This is taken from a php for loop that prints out 100 rows.

<tr>
    <td class="td-code"><input id="code'.$i.'" name="code'.$i.'" type="text" class="code'.$i.' order-code" value="'.@$orderItem->{'code'.$i}.'" /></td>
    <td class="td-price"><input ng-model="price'.$i.'" class="order-price" id="price'.$i.'" name="price'.$i.'" type="number" value="'.@$orderItem->{'price'.$i}.'" step="0.50"/></td>
    <td class="td-quantity"><input ng-model="quantity'.$i.'" class="order-price" id="quantity'.$i.'" name="quantity'.$i.'" type="number" value="'.@$orderItem->{'quantity'.$i}.'" /></td>
    <td class="td-discount"><input ng-model="discount'.$i.'" class="order-price" id="discount'.$i.'" name="discount'.$i.'" type="number" value="'.@$orderItem->{'discount'.$i}.'" /></td>
    <td class="td-total"><span class="row-total" ng-model="total'.$i.'" id="total'.$i.'" class="order-price" id="total'.$i.'" valid-number/>{{(price'.$i.' * quantity'.$i.') / 100 * (100 - discount'.$i.') | number:2}}</span></td>
</tr>

Example one of a watch that returns nothing for me. I am just trying to at least add the first two total together and display them

$scope.$watch("total1", function (newValue, oldValue) {

    $scope.updated_info = $scope.total1 + $scope.total2;            

});

Then when I put {{updated_info}} or {{scope.updated_info}} I dont see anything.

Example two code which I put in the controller app.

$scope.total = function() {
    var total = parseFloat($scope.total1 || 0) + parseFloat($scope.total2 || 0) +
                parseFloat($scope.total3 || 0) + parseFloat($scope.total4 || 0) + 
                parseFloat($scope.total5 || 0);
    return total || 0;
};

Then when I put {{total}} or {{scope.total}} again I see nothing.

Upvotes: 0

Views: 60

Answers (1)

Manikandan Velayutham
Manikandan Velayutham

Reputation: 2228

Your code have many mistakes and {{total()}} is outside of ng-controller div. See my simple answer below.

<!DOCTYPE html>
<html>

<head>
  <script data-require="[email protected]" data-semver="1.4.2" src="https://code.angularjs.org/1.4.2/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
  <style>
    td {
      width: 100px;
    }
    input {
      width: 100px;
    }
  </style>
</head>

<body>
  
  <style type="text/css">
    /* style the auto-complete response */
    
    li.ui-menu-item {
      font-size: 12px !important;
    }
  </style>
  <div ng-app="myApp" ng-controller="OrderController" class="row">
    <div class="page-header">
      <h1>Order Form</h1>
      <form onsubmit="return false;">
        <table>
          <thead>
            <tr>
              <th>Image</th>
              <th>Code</th>
              <th>Desc</th>
              <th>Price</th>
              <th>Qty</th>
              <th>Total</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                <div class="order-image">
                  <span id="image1"></span>
                </div>
              </td>
              <td>
                <input id="code1" type="text" class="code1 order-code" />
              </td>
              <td>
                <input class="order-prod_desc" id="prod_desc1" type="text" />
              </td>
              <td>
                <input ng-model="price1" placeholder="price" ng-change="change();" class="order-price" id="price1" name="price1" type="number" />
              </td>
              <td>
                <input ng-model="quantity1" placeholder="quantity" ng-change="change();" class="order-price" id="quantity1" type="number" value="" />
              </td>
              <td>
                <input class="order-price" placeholder="total" ng-model="total1" ng-disabled="true" id="total1" type="number" step="0.01" />
              </td>
            </tr>
            <tr>
              <td>
                <div class="order-image">
                  <span id="image2"></span>
                </div>
              </td>
              <td>
                <input id="code2" type="text" class="code2 order-code" />
              </td>
              <td>
                <input class="order-prod_desc" id="prod_desc2" type="text" />
              </td>
              <td>
                <input ng-model="price2" placeholder="price" ng-change="change();" class="order-price" id="price2" name="price2" type="number" />
              </td>
              <td>
                <input ng-model="quantity2" placeholder="quantity" ng-change="change();" class="order-price" id="quantity2" type="number" value="" />
              </td>
              <td>
                <input class="order-price" placeholder="total" ng-model="total2" ng-disabled="true" id="total2" type="number" value="" step="0.01" />
              </td>
            </tr>
          </tbody>
        </table>
      </form>
    </div>
      <h2>Total: {{total()}}</h2>
  </div>

  <script>
    var myApp = angular.module('myApp', []);



    myApp.controller('OrderController', function($scope) {

$scope.change = function(){
  $scope.total1 = ($scope.price1 || 0)  * ($scope.quantity1 || 0);
$scope.total2 = ($scope.price2 || 0 ) * ($scope.quantity2 || 0);
}

      $scope.total = function() {
        var total = parseFloat($scope.total1 || 0) + parseFloat($scope.total2 || 0);
        return total || 0;
        
      };
    });
  </script>
  </body>

</html>

Upvotes: 1

Related Questions