Nathan Hyland
Nathan Hyland

Reputation: 860

Nested unique ng-model per ng-repeat

Currently creating a page that has nested ng-repeats and ng-models. The ng-models are based off an $index.

http://codepen.io/natdm/pen/vOzaPj?editors=101 (since jsfiddle had an out-dated Angular)

Controller:

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

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

    $scope.league = { teams: 5,
                     format: 4}

    $scope.toArray = function(team) {
        return new Array(team);
    };

    $scope.log = function(data) {
        console.log(data);
    };

});

HTML:

<div class="container" ng-app="myApp" ng-controller="teamController">
    <h1>Create Teams</h1>

    <table ng-repeat="t in toArray(league.teams) track by $index">
        <thead class="col-md-6">
        <tr>
            <th>Team {{$index + 1}}</th>
        </tr>
        </thead>
        <tbody class="col-md-6">
        <tr>
            <td>Team Name</td>
            <td><input type="text" ng-model="team.team_name"/></td>
        </tr>
        <tr ng-repeat="p in toArray(league.format) track by $index">
            <td>Player {{$index + 1}}</td>
            <td><input type="text" ng-model="team.player_+[$index + 1]"/></td>

        </tr>
        </tbody>
    </table>

    <button ng-click="log(team)">Test</button>

</div>

I'm pulling the number of teams and players per team from a Factory. They equate to just two numbers. Maybe 5 teams with 4 players each. This would make a page with five repeating tables, having rows for 4 players and a team name, each.

I'm trying to think of a way to send these to the database. Since this page is rendered off the amount of teams and players, the only way to make the ng-models are off of an $index.

The database has the following columns (subject to change if needed):

How can I have one page with repeating team fields upload multiple teams at once with one $http.put request?

Further more, maybe a smaller issue, with the way I have it set, it's forcing the input of each text to be the ng-model name. That'd have to change.

Upvotes: 1

Views: 1314

Answers (2)

Panchanand Mahto
Panchanand Mahto

Reputation: 151

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

myApp.controller('teamController', function($scope) {
    $scope.team={};
    $scope.league = { teams: 5,
                     format: 4}

    $scope.toArray = function(team) {
        return new Array(team);
    };

    $scope.log = function(data) {
        console.log(data);
    };

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container" ng-app="myApp" ng-controller="teamController">
    <h1>Create Teams</h1>

    <table  ng-repeat="p in toArray(league.teams) track by $index">
        <thead class="col-md-6">
        <tr>
            <th>Team {{$index + 1}}</th>
        </tr>
        </thead>
        <tbody class="col-md-6">
        <tr>
            <td>Team Name</td>
            <td><input type="text" ng-model="team['team_'+($index+1)].team_name"/></td>
        </tr>
        <tr ng-repeat="p in toArray(league.format) track by $index" ng-init="innerIndex=$index">
            <td>Player  {{$index + 1}}</td>
            <td><input type="text" ng-model="team['team_'+($parent.$index+1)].player['player_'+(innerIndex + 1)]"/></td>

        </tr>
        </tbody>
    </table>

    <button ng-click="log(team)">Test</button>
  <div>
  JSON: <br>{{team}}
  </div>

</div>

Upvotes: 0

Vanojx1
Vanojx1

Reputation: 5584

i think you need to parse your structure in a new one

$scope.parseLeague = [];

for(var i=0;i<$scope.league.teams ;i++){
  $scope.parseLeague.push({team: "team_"+i, players: []});
  for(var j=0;j<$scope.league.format;j++){
    $scope.parseLeague[i].players.push("player_"+j);
  }
}

then inside the html you need to change the repeat with the new structure

<table ng-repeat="team in parseLeague track by $index">

with

<tr>
    <td>Team Name</td>
    <td><input type="text" ng-model="team.name"/></td>
</tr>

and

<tr ng-repeat="player in team.players track by $index">
    <td>Player {{$index + 1}}</td>
    <td><input type="text" ng-model="player"/></td>
</tr>

the http request

var request = $http({
    method: "post",
    url: "yoururl",
    data: { teamsdata: angular.toJson($scope.parseLeague)}
});
request.success(
    function( risp ) {
        //handle your risp
    }
);

working pen http://codepen.io/anon/pen/xGaaRP?editors=101

Upvotes: 2

Related Questions