Reputation: 105
I have a little issue on my first AngularJS project. To sum up I have a JSON that I load using a service to create tables.
This JSON looks like this :
[ { id: 5, year: 2018, data: [{id:1, name:"John Doe", age: 28},...] }, ... ]
For each element in my JSON I create a table and I populate each table with each sub-element (data). Then I implemented a sorting system for my table. When I click on one of the th, it sorts data.
Here is a sample of my HTML code :
<table ng-repeat="elem in json">
<thead>
<tr>
<th ng-click="sortData('id')">ID <i ng-class="getSortClass('id')"></i></th>
<th ng-click="sortData('name')">Name <i ng-class="getSortClass('name')"></i></th>
<th ng-click="sortData('age')">Age <i ng-class="getSortClass('age')"></i></th>
<th>....</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in elem.data | orderBy:sortColumn:reverseSort">
<td>...</td>
....
</tr>
</tbody>
</table>
Here is a sample of my JS code:
$scope.sortColumn = "name";
$scope.reverseSort = false;
$scope.sortData = function (column) {
$scope.reverseSort = ($scope.sortColumn == column) ? !$scope.reverseSort : false;
$scope.sortColumn = column;
}
$scope.getSortClass = function (column) {
if ($scope.sortColumn == column) {
return $scope.reverseSort
? 'fa fa-chevron-down'
: 'fa fa-chevron-up';
}
return '';
}
It actually works, however the thing is I want each table to be independent of each other. Currently if I sort for instance the "name" column in the first generated table, it also sorts the "name" other tables.
Is there a way to apply the sorting to the table from where the click was made? I thought to add a parameter that would be the id of the table or something of the kind. I didn't try that at for now but is it good idea or is there a proper way to do that?
Thanking you in advance,
Upvotes: 1
Views: 64
Reputation: 787
Based on the code, it looks like the tables may be sharing one scope, including the sortColumn property. If that's the case, changing it in one table will sort all tables. You can mitigate this by making each table a directive or component with an isolated scope.
I.E. you could have something like
<my-custom-table elem="elem" ng-repeat="elem in json">
</my-custom-table>
And then you would define my-custom like a directive with an isolated scope like so:
angular.module('yourApp').directive('myCustomTable', function () {
return {
scope: {
elem: '='
},
link: function(scope){
scope.getSortClass=function(){…}
scope.sortData=function(){…}
},
templateUrl: 'path_to_my_custom_table.html'
};
});
And then the template of my_custom_table.html would just be
<table>
<thead>
<tr>
<th ng-click="sortData('id')">ID <i ng-class="getSortClass('id')"></i></th>
<th ng-click="sortData('name')">Name <i ng- class="getSortClass('name')"></i></th>
<th ng-click="sortData('age')">Age <i ng- class="getSortClass('age')"></i></th>
<th>....</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in elem.data | orderBy:sortColumn:reverseSort">
<td>...</td>
....
</tr>
</tbody>
</table>
Upvotes: 0
Reputation: 1303
You want a sort variable for each of your tables, But you are sharing a global variable which every table looks for. There are several solutions. One that come to my mind is to have a list of sort columns and use it for each table:
$scope.sortColumn = [];
$scope.reverseSort = [];
$scope.sortData = function (id, column) {
$scope.reverseSort[id] = ($scope.sortColumn[id] == column) ? !$scope.reverseSort[id] : false;
$scope.sortColumn[id] = column;
}
and change your ng-repeat
accordingly:
<tr ng-repeat="row in elem.data | orderBy:sortColumn[id]:reverseSort[id]">
and in the same way your $scope.getSortClass
method.
also your ng-click
becomes this:
<th ng-click="sortData(elem.id, 'id')">
Upvotes: 3