Angularjs,将列总和限制为x

时间:2016-03-09 20:42:51

标签: javascript angularjs

我是Angularjs的新手,并且无法实现客户端验证。感谢这个post我能够限制用户输入,但现在我需要将每列的总和限制为24.目前我能够对列进行求和,但是我很难进行交互使用它,如果新的总和超过24,则将其值设置回旧值。这是fiddle,其中包含我当前的代码。



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

app.controller('Ctrl', function($scope) {

  $scope.Rows = [{
    FriHrs: 0,
    SatHrs: 0,
    SunHrs: 0,
    MonHrs: 0,
    TueHrs: 0,
    WedHrs: 0,
    ThuHrs: 0
  }];

  $scope.AddRow = function() {
    $scope.Rows.push({
      FriHrs: 0,
      SatHrs: 0,
      SunHrs: 0,
      MonHrs: 0,
      TueHrs: 0,
      WedHrs: 0,
      ThuHrs: 0
    })
  };
});

app.filter('sumByKey', function() {
  return function(data, key) {
    if (typeof(data) === 'undefined' || typeof(key) === 'undefined') {
      return 0;
    }
    var sum = 0.0;
    for (var i = data.length - 1; i >= 0; i--) {
      sum += parseFloat(data[i][key]);
    }
    return sum;
  };
});

app.directive('numberOnlyInput', function() {
  return {
    restrict: 'EA',
    template: '<input style="width:30px" ng-model="inputValue"/>',
    scope: {
      inputValue: '=',
    },
    link: function(scope) {
      scope.$watch('inputValue', function(newValue, oldValue) {
        var arr = String(newValue).split("");
        var arr2 = String(newValue).split(".");
        if (arr.length === 0) return;
        if (arr.length === 1 && arr[0] === '.') return;
        if (arr.length === 2 && newValue === '.') return;
        if (arr2.length === 2) {
          if (arr2[1].length === 3) {
            scope.inputValue = oldValue;
          }
        }

        if (isNaN(newValue)) {
          scope.inputValue = oldValue;
        }
      });
    }
  };
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<table ng-app="myapp" ng-controller="Ctrl" class="table">
    <thead>
        <tr>
            <th>Sat<br/><span id="totalSat"></span><small>{{Rows|sumByKey:'SatHrs'}}</small></th>
            <th>Sun<br/><span id="totalSun"></span><small>{{Rows|sumByKey:'SunHrs'}}</small></th>
            <th>Mon<br/><span id="totalMon"></span><small>{{Rows|sumByKey:'MonHrs'}}</small></th>
            <th>Tue<br/><span id="totalTue"></span><small>{{Rows|sumByKey:'TueHrs'}}</small></th>
            <th>Wed<br/><span id="totalWed"></span><small>{{Rows|sumByKey:'WedHrs'}}</small></th>
            <th>Thu<br/><span id="totalThu"></span><small>{{Rows|sumByKey:'ThuHrs'}}</small></th>
            <th>Fri<br/><span id="totalFri"></span><small>{{Rows|sumByKey:'FriHrs'}}</small></th>
        </tr>
    </thead>
    <tbody id="detailTable">
        <tr ng-repeat="Row in Rows">
            <td><number-only-input input-value="Row.SatHrs"/></td>
            <td><number-only-input input-value="Row.SunHrs"/></td>
            <td><number-only-input input-value="Row.MonHrs"/></td>
            <td><number-only-input input-value="Row.TueHrs"/></td>
            <td><number-only-input input-value="Row.WedHrs"/></td>
            <td><number-only-input input-value="Row.ThuHrs"/></td>
            <td><number-only-input input-value="Row.FriHrs"/></td>
        </tr>
        <tr>
            <td colspan="7"><input type="button" value="Add Record" ng-click="AddRow()"/></td>
        </tr>
    </tbody>
</table>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

您可以向指令添加属性:

https://jsfiddle.net/r21er55y/ [已为列更新]

HTML

<td><number-only-input input-value="Row.SatHrs" 
        allow="checkTotal(Row, Rows, 'SatHrs')"/></td>

JS

app.directive('numberOnlyInput', function() {
  return {
    restrict: 'EA',
    template: '<input style="width:30px" ng-model="inputValue"/>',
    scope: {
      inputValue: '=',
      allow: '&'
    },
    link: function(scope) {
      scope.$watch('inputValue', function(newValue, oldValue) {
        var arr = String(newValue).split("");
        var arr2 = String(newValue).split(".");
        if (arr.length === 0) return;
        if (arr.length === 1 && arr[0] === '.') return;
        if (arr.length === 2 && newValue === '.') return;
        if (arr2.length === 2) {
          if (arr2[1].length === 3) {
            scope.inputValue = oldValue;
          }
        }

        if (isNaN(newValue)) {
          scope.inputValue = oldValue;
        }
        if(!scope.allow(scope)) {
          scope.inputValue = oldValue;
        }
      });
    }
  };
});

你的控制器可以检查它:

  $scope.checkTotal = function(row, rows, prop) {
    var rowTotal = Object.keys(row).reduce(function (previous, key) {
        if(key.indexOf('Hrs') === -1) return previous;
        return previous + parseInt(row[key],10);
      }, 0);
    var colTotal = rows.reduce(function(previous, row){
        return previous + parseInt(row[prop],10);
      }, 0);
    return rowTotal < 25 && colTotal < 25;
  }