Open pirtleshell opened 7 years ago
I'm hoping there is (or can eventually be) a better way, but I worked out a hacky way to do it. I tried not to alter angular-tablesort.js
but I ended up having to add one line. Here's how I did it:
add tablesort's setSortField
to its scope by adding $scope.setSortField = this.setSortField
to angular-tablesort.js
after the function is defined
access the table's scope and current sort order in the desired controller by extracting it from the tablesort:sortOrder
event. This will fire when the component mounts assuming one of your column heads has the ts-default
attribute:
let tableScope, currentSortOrder;
$scope.$on('tablesort:sortOrder', function(event, sortOrder) {
tableScope = event.targetScope;
currentSortOrder = sortOrder;
});
This is pretty un-angular... Tablesort should maybe have a service that lets you communicate between controllers? This also wouldn't work well on a page with multiple sorting tables
Now to change the sort order, you just need to call tableScope.setSortField(sortexpr, element, name, sortBy)
.
I wrote the following function to easily sort by a column given its zero-indexed number.
// first get the column sorting info after the table mounted
// cols is an array of objects containing the DOM element and ts-criteria of the each table head
const cols = angular.element('th').map(function(i, el) {
const element = angular.element(el);
const name = element.attr('ts-criteria');
return {element, name};
});
// then you can call this function to sort by a column
$scope.sortByColumn = function(whichCol, order) {
// order follows tablesort convention.
// descending => order=true
// ascending => order=false
const element = cols[whichCol].element;
const name = cols[whichCol].name;
let timesToSort = 0;
// descending needs to set sort field twice if not already on proper column
if (order && currentSortOrder.name !== name)
timesToSort++;
if (currentSortOrder.name !== name || currentSortOrder.order)
timesToSort++;
while (timesToSort--) tableScope.setSortField(name, element);
}
Now from your view you can have something like
<button ng-click='sortByColumn(3, true)'>Sort 4th column descending</button>
Obviously, the column must have a ts-criteria
attribute set.
If you have more than one table on the page, then the indices will be off. However you can have cols
only get the th
tags of a specific table (angular.element('#specificTable th')
). But you'll need to handle currentSortOrder
and tableScope
differently.
What do people think of this? Is there a better way to do it?
Is there a function I can call that is the equivalent of clicking one of the columns names?
For instance, clicking a button outside of the table could call the function to change which column the sorting is based on.
My use case is that I have a UI outside the table that changes what data the table contains and it makes more sense for some data to be sorted by one column and others by a different one. I'd like to programatically change which column the table is sorted by when the user clicks to change the table data.