1) Sorting the information according to subject
To begin, organize the data by subject
and then calculate the quantity of items in each category.
You can utilize the angular.filter module's groupBy filter for this purpose.
1a) Add a dependency on that module as shown below:
var app = angular.module("yourModuleName", ["angular.filter"]);
1b) Subsequently, employ the groupBy
filter within an ng-repeat
directive on a <tbody>
tag like so:
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
1c) The data will now be structured in the format outlined below. This constitutes an object consisting of key
/value
pairs where "maths"
and "history"
function as keys
, with the arrays serving as the corresponding values
:
{
"maths": [
{
"rollno": 1,
"name": "abc",
"subject": "maths",
}
],
"history": [
{
"rollno": 4,
"name": "xyz",
"subject": "history",
},
{
"rollno": 2,
"name": "pqr",
"subject": "history",
}
]
}
2) Presenting the organized data and tallying the entries in each category
Employ key
and value
to showcase the categorized data in a table as demonstrated here:
<table>
<thead>
<tr>
<th>Subject</th>
<th>Number of Students</th>
<th>Expand/Collapse</th>
</tr>
</thead>
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
<tr>
<td>{{ key }}</td>
<td>{{ value.length }}</td>
<td>
<button>
Expand/Collapse
</button>
</td>
</tr>
<tr>
<td colspan="3">
<table>
<thead>
<tr>
<th>Roll Number</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="student in value">
<td>{{ student.rollno }}</td>
<td>{{ student.name }}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Note the additional <tr>
and nested table featuring another ng-repeat
to exhibit the student details. At present, all nested student records will be visible; the subsequent step involves selectively displaying or concealing the nested tables based on the expand/collapse button clicked.
3) Revealing/Concealing the grouped student data
3a) Append an ng-click
directive to the button so it transmits the key
to an onExpandClicked
function residing within your controller:
<button ng-click="onExpandClicked(key)">
Expand/Collapse
</button>
3b) Formulate the onExpandClicked
function within your controller:
$scope.onExpandClicked = function(name){
$scope.expanded = ($scope.expanded !== name) ? name : "";
}
This assigns a value on the $scope
which can determine whether to reveal/conceal a segment of student data in the view. The key
is relayed into the function as the name
parameter, whereby $scope.expanded
will either adopt the value of name
or reset to ""
contingent on whether the provided name
aligns with the current $scope.expanded
content.
3c) Lastly, leverage the $scope.expanded
variable within an ng-if
directive featured on the second <tr>
tag within <tbody>
to show or hide the nested student data:
<table>
<thead>
<tr>
<!-- Excluded for brevity -->
</tr>
</thead>
<tbody ng-repeat="(key, value) in data | groupBy: 'subject'">
<tr>
<!-- Excluded for brevity -->
</tr>
<tr ng-if="expanded === key">
<!--
Excluded for brevity
-->
</tr>
</tbody>
</table>
Demo
CodePen: Demonstrating how to display/hide categorized data created using the angular.filter module's groupBy filter