Reputation: 25914
I have an ng-repeat
creating rows, and I want to insert a new row periodically, but the logic for creating this is inside the row and ends up messing up the nesting, for example:
<tr ng-repeat='item in items'>
<!-- this doesn't work well -->
<tr ng-if='items[$index].day != items[$index-1].day'>
<td colspan=2>
NEW DAY
</td>
</tr>
<td>{{item.name}}</td>
<td>{{item.day}}</td>
</tr>
I want the "day divider" rows amongst the data rows whenever the day changes.
Upvotes: 2
Views: 2889
Reputation: 3429
You can use repeat-start and repeat-end:
<tr ng-repeat-start="item in items">
<td>{{item.name}}</td>
<td>{{item.day}}</td>
</tr>
<tr ng-repeat-end>
<td colspan="2">
</tr>
Upvotes: 0
Reputation: 3429
Plz try this one
<body ng-app="ngAnimate">
Click me: <input type="checkbox" ng-model="checked" aria-label="Toggle ngHide"><br/>
<div>
Show:
<div class="check-element animate-show" ng-show="checked">
<span class="glyphicon glyphicon-thumbs-up"></span> I show up when your checkbox is checked.
</div>
</div>
<div>
Hide:
<div class="check-element animate-show" ng-hide="checked">
<span class="glyphicon glyphicon-thumbs-down"></span> I hide when your checkbox is checked.
</div>
</div>
</body>
Upvotes: 0
Reputation: 25914
This works although it seems gross:
<tr ng-repeat-start='item in items'>
<tr ng-if='items[$index].day != items[$index-1].day'>
<td colspan=2>
NEW DAY
</td>
</tr>
<td>{{item.name}}</td>
<td>{{item.day}}</td>
</tr>
<!-- dummy row -->
<tr ng-repeat-end></tr>
Upvotes: 0
Reputation: 21684
Sounds like you might want to group the data by days and do two nested repeaters.
angular.module('app', []);
angular.module('app').controller('Ctrl', function($scope) {
$scope.rows = [
{ name: 'one', day: 'monday' },
{ name: 'two', day: 'monday' },
{ name: 'three', day: 'tuesday' },
{ name: 'four', day: 'tuesday' },
{ name: 'five', day: 'thursday' }
];
var groupBy = function(arr, property) { // you can use Underscore instead
var output = {};
for (var i = 0; i < arr.length; i++) {
var item = arr[i];
if (typeof output[item[property]] === 'undefined') {
output[item[property]] = [];
}
if (item.hasOwnProperty(property)) {
output[item[property]].push(item);
}
}
return output;
};
$scope.groupedRows = groupBy($scope.rows, 'day');
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="Ctrl">
<table>
<!-- it's valid to have more than one tbody -->
<tbody ng-repeat="(key, group) in groupedRows">
<tr>
<th colspan="2">{{key}}</th>
</tr>
<tr ng-repeat="row in group">
<td>{{row.name}}</td>
<td>{{row.day}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Note: if you want the grouped rows to be ordered properly, you might want to store your day as an integer, and only change how it displays. Since you can't "actually" sort object keys, they auto-sort alphabetically in the JS engine, you can have them sorted properly if they are numeric.
Upvotes: 0
Reputation: 4156
UPDATE
What about having new method in your controller like isDivider(item)
which would return bool value.
I did not test this but it should work:
<tr ng-repeat='item in items'>
<td ng-if="isDivider(item)==true" colspan=2>NEW DAY<td>
<td ng-if="isDivider(item)==false">{{item.name}}</td>
<td ng-if="isDivider(item)==false">{{item.day}}</td>
</tr>
Upvotes: 0