Using AngularJS, I'm iterating over a JSON object containing an array of event objects, containing an array of competition objects.
I wish to show each event
in a table, and then each competition
in a td
, but only three cells per row
I'm using ng-repeat to return a list of tables for each event, but I'm having trouble with splitting the competitions into a new <tr>
every three <td>
s
Aside from rebuilding my own massive object from the JSON, what is the best way to do what I'm describing in Angular?
Current view:
<table ng-repeat="listing in listings">
<tr>
<th colspan="3">{{listing.name}}</th>
</tr>
<tr>
<td ng-repeat="competition in listing.competitions">
{{competition.id}} - {{competition.name}}
</td>
</tr>
</table>
Desired output:
<table>
<tr>
<th colspan="3">Event Name</th>
</tr>
<tr>
<td>competition id - competition name</td>
<td>competition id - competition name</td>
<td>competition id - competition name</td>
</tr>
<tr>
<td>competition id - competition name</td>
<td>competition id - competition name</td>
<td>competition id - competition name</td>
</tr>
</table>
Controller:
app.controller('EventsCtrl', function ($scope, $http) {
$scope.loading = true;
$http.get('scripts/JSON/events.json').then(function (response) {
var listings = response['data'].events;
$scope.listings = listings;
});
});
events.json
{
"events": [
{
"id": 418,
"name": "et ullamco",
"competitions": [
{
"id": 933,
"name": "qui in deserunt occaecat et",
"startTime": 1381092189
},
{
"id": 853,
"name": "eu enim ex incididunt do",
"startTime": 1380708266
},
{
"id": 5738,
"name": "ad est ut aliquip et",
"startTime": 1381366623
},
{
"id": 7599,
"name": "sit ex voluptate aliqua dolor",
"startTime": 1381284106
},
{
"id": 7481,
"name": "laborum consequat deserunt do aliqua",
"startTime": 1380874273
},
{
"id": 3441,
"name": "amet reprehenderit sint sunt proident",
"startTime": 1380554850
},
{
"id": 1959,
"name": "ullamco minim minim in voluptate",
"startTime": 1380651981
}
]
},
You can add condition using ng-if also and this is effective too. You can apply any condition to your list using ng-if attribute. In below example, I have put condition where Age > 20 and IsActive is true. ng-repeat will fetch all records which full fill this scenario.
You can nest two ng-repeat together in order to create a more complex table. The first ng-repeat in the tr tag will create the rows and the second one in the td tag will create one column per element in the collection.
Each iteration of ng-repeat creates a new child scope, and that new child scope always gets a new property.
Note: The $index variable is used to get the Index of the Row created by ng-repeat directive. Each row of the HTML Table consists of a Button which has been assigned ng-click directive. The $index variable is passed as parameter to the GetRowIndex function.
You are using a table but the semantics of your data indicate you have a list of lists. You should consider outputting this with <ul><li>
instead of a grid.
<ul ng-repeat="listing in listings">
<li>
<h2>{{listing.name}}</h2>
<ul ng-repeat="competition in listing.competitions">
<li>
{{competition.id}} - {{competition.name}}
</li>
</ul>
</li>
</ul>
You can achieve your desired layout with CSS quite easily using the above HTML. Checkout the "block grids" in Twitter Bootstrap or Foundation for examples. Tables should generally be used only for data that is actually tabular.
However...
You're question does still bear answering since there may be other reasons to alternate templates in the way you suggest. You could use a function for this to get things three at a time:
<table ng-repeat="listing in listings">
<tr>
<th colspan="3">{{listing.name}}</th>
</tr>
<tr ng-repeat="group in competitions">
<td ng-repeat="competition in group">
{{competition.id}} - {{competition.name}}
</td>
</tr>
</table>
In your controller you can create a "list of lists" to bind to the nested repeaters
// Adapted from Fresheyeball's solution
$scope.competitions = []
compSet = []
for(var i; i < $scope.listings.competitions; i++){
var competition = $scope.listings.competitions[i];
if( i % 3 ){
$scope.competitions.push(compSet);
compSet = [];
}
compSet.push(competition);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With