Repeating a set of <td> s in the same table row using AngularJS
I want to create a table that in its header contains the names of each player for each of the two teams. The scope has a variable teams
which is a list of Team objects, each with a list of Player objects as an attribute.
This turned out to be much more difficult than I expected.
<table>
<thead>
<tr>
<div ng-repeat="team in teams">
<th ng-repeat="player in team.players">{[ player.name ]}</th>
<th>Partial Score</th>
<th>Total Score</th>
</div>
</tr>
</thead>
</table>
- the easiest thing I mean - but it doesn't work. cannot be placed inside a according to the W3C (from what I understand), so the browser just takes the div and puts it outside the table.
I've tried directives too, but that doesn't help. This is an example of my directive file.
<th ng-repeat="player in team.players">{[ player.name ]}</th>
<th>Partial Score</th>
<th>Total Score</th>
For example, if I have a <player-initials>
c directive replace: 'false'
, the browser will push the <25> element out of the table. Installation replace: 'true'
, fixes this, but then I get an error because the directive contains more than one root element. I can't wrap the elements in the directive with anything, because that would result in invalid HTML (as above).
I have tried all combinations of element directives and attributes and replace, nothing gives me what I want. Any help?
source to share
I figured it out using the ng-repeat-start and ng-repeat-end directives. I really didn't want to write functions to generate HTML for me because that is why I switched to Angular in the first place.
Here's a screenshot: http://i.imgur.com/e5LBvQB.png .
This is the code (stripped down for the relevant part) for the header only, everything else is similar. The only "hacky" part I don't like is the ng-show attributes for B and T to undo it correctly, but it works for me right now. I think I can clean it up with directives.
<table class="table table-condensed table-striped table-hover table-responsive">
<thead>
<tr>
<th ng-repeat-start="team in game.getTeams()" ng-hide="true"></th>
<th ng-repeat="player in team.getPlayers()" ng-class="$parent.$first && 'text-info' || 'text-danger'">
<u>
{[ player.name | truncate ]}
</u>
</th>
<th ng-repeat-end ng-show="$first">
#
</th>
</tr>
</thead>
</table>
source to share
You have to add a method to your scope that does the logic for you.
Something like this should work:
$scope.getAllPlayers = function() {
var players = [];
this.teams.forEach(function(team){
players = players.concat(team.players);
});
return players;
}
Then in your home:
<table>
<thead>
<tr>
<th ng-repeat="player in getAllPlayers()">{{ player.name }}</th>
<th>Partial Score</th>
<th>Total Score</th>
</tr>
</thead>
</table>
I am not using Angular, so I might be wrong, but I am sure this is the way to go. This kind of logic should be in your controller as simple is a nested loop.
EDIT: Referring to the comments, you can create a function that returns your header cells the way you want.
$scope.getHeaderCells = function() {
var cells = [];
this.teams.forEach(function(team){
cells = cells.concat(team.players.map(function(player){
return { team: team, value: player.name };
})).concat([
{team: team, value: 'Partial Score'},
{team: team, value: 'Total Score'}
]);
});
console.log(cells);
return cells;
}
from
<th ng-repeat="cell in getHeaderCells()">{{ cell.value }}</th>
here is the violin
source to share
Created a violin here .
Hope this is what you are looking for if you don’t tell me the format you are looking for. Your HTML should look something like this.
<table ng-repeat="team in teams">
<tr>
<td colspan="3">
{{team.name}}
</td>
</tr>
<tr>
<td>Player Name</td>
<td>Partial Score</td>
<td>Total Score</td>
</tr>
<tr ng-repeat="player in team.players">
<td>{{player.name}}</td>
<td>{{player.PScore}}</td>
<td>{{player.TScore}}</td>
</tr>
</table>
source to share