Search code examples
angularjsangularjs-ng-repeathtml-table

Angular ng-repeat on table with data input


The answer appears to be that the two way data binding works if you have an array of objects going to an ng-repeat, but did doesn't work if you have an array of strings.

I wish to provide a UI where users can input multiple recipients. I've got an array of names called "receivers". My thought was I could display a table using ng-repeat, like so:

<table>
    <tr ng-repeat = "receiver in receivers">
        <td><input type = "text" ng-model = "receiver"></td>
        <td><div ng-click = "addRecipient(receiver)">+</div></td>
        <td><div ng-click = "deleteRecipient(receiver)">-</div></td>
    </tr>
</table>

The problem I'm running in to is that I know of no way to get the contents of "receiver" back to my controller, other than from the calls to addRecipient or deleteRecipient. Which makes it hard for me to use that data.

Any suggestions would be greatly appreciated. If there's a better or "more correct" way to do this, I'd love to see it.


Solution

  • You don't need to do anything extra. Whatever text is typed into the text fields on your page will automatically be present in your $scope.receivers array. I always define my scope variable explicity in my controller.

    I have a working example but using a simple object instead of Strings, that could be the issue.

    http://plnkr.co/edit/g66KTkDPlWt0xs5EZrrx?p=preview

    script:

    var app = angular.module('plunker', []);
    
    app.controller('MainCtrl', function($scope) {
      $scope.name="Nick";
      $scope.receivers=[{value:"First"}];
    
      $scope.addRecipient = function(receiver) {
        $scope.receivers.push({value:""});
      }
    
      $scope.deleteRecipient = function(receiver) {
        for(var i=0; i<$scope.receivers.length; i++) {
          if($scope.receivers[i] === receiver) {
            $scope.receivers.splice(i, 1);
            break;
          }
        }
      }
    
      $scope.showme = function() {
        var s = "";
        for(var i=0; i<$scope.receivers.length; i++) {
          s = s + i + ": " + $scope.receivers[i].value + "\n";
        }
        alert(s);
      };
    
    });
    

    html:

    <!DOCTYPE html>
    <html ng-app="plunker">
    
      <head>
        <meta charset="utf-8" />
        <title>AngularJS Plunker</title>
        <script>document.write('<base href="' + document.location + '" />');</script>
        <link rel="stylesheet" href="style.css" />
        <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
        <script src="app.js"></script>
      </head>
    
      <body ng-controller="MainCtrl">
        <p>Hello {{name}}!</p>
    
        <table>
            <tr ng-repeat = "receiver in receivers">
                <td><input type="text" ng-model="receiver.value"></td>
                <td><div ng-click="addRecipient(receiver)">+</div></td>
                <td><div ng-click="deleteRecipient(receiver)">-</div></td>
            </tr>
        </table>    
    
        <button ng-click="showme()">Show Me Contents</button>
    
      </body>
    
    </html>