I have an HTML table and want to sort my records ($scope.records
in ctrl) by clicking on table headers ($scope.headers
in ctrl),
Can anyone
I don't know what sort of data is in your records, so for my sample I just used an array of JSON values. I have tried several different sorting plugins for my Javascript with Angular and nothing worked. In the long run I have discovered you don't necessarily need those extras.
Since AngularJS is good at processing javascript data-structures for displaying in HTML, you can just rearrange the javascript-arrays in memory, and AngularJS picks up on the changes. This example allows clicking the headers of the table, which will trigger a sorting based on that columns data type. If it is already sorted on that column, it will reverse-sort the column. The type detection is done through the presented isNumeric() function, and one two-tiny tweaks:
var app = angular.module("app", []);
app.controller("MainController", function($scope) {
$scope.samplePositions = [
{"#": "1", "Unique ID": "100130", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 1 - Box 1 - Position 1", "Status": "Available"},
{"#": "2", "Unique ID": "100131", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 1 - Box 1 - Position 2", "Status": "Available"},
{"#": "3", "Unique ID": "100132", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 1 - Box 1 - Position 3", "Status": "Available"},
{"#": "4", "Unique ID": "100133", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 1 - Box 1 - Position 4", "Status": "Available"},
{"#": "5", "Unique ID": "100134", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 1 - Box 1 - Position 5", "Status": "Checked Out"},
{"#": "6", "Unique ID": "100135", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 1 - Box 1 - Position 6", "Status": "Checked Out"},
{"#": "7", "Unique ID": "100136", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 1 - Box 1 - Position 7", "Status": "Checked Out"},
{"#": "8", "Unique ID": "100137", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 1 - Box 1 - Position 8", "Status": "Checked Out"},
{"#": "9", "Unique ID": "100138", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 1 - Box 1 - Position 1", "Status": "Available"},
{"#": "10", "Unique ID": "100139", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 2 - Box 1 - Position 1", "Status": "Available"},
{"#": "11", "Unique ID": "100140", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 2 - Box 1 - Position 2", "Status": "Available"},
{"#": "12", "Unique ID": "100141", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 2 - Box 1 - Position 3", "Status": "Lost"},
{"#": "13", "Unique ID": "100142", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 2 - Box 1 - Position 4", "Status": "Lost"},
{"#": "14", "Unique ID": "100143", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 3 - Box 1 - Position 1", "Status": "Available"},
{"#": "15", "Unique ID": "100144", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 3 - Box 1 - Position 2", "Status": "Available"},
{"#": "16", "Unique ID": "100145", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 4 - Box 1 - Position 1", "Status": "Checked Out"},
{"#": "17", "Unique ID": "100146", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 4 - Box 1 - Position 2", "Status": "Available"},
{"#": "18", "Unique ID": "100147", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 4 - Box 1 - Position 3", "Status": "Available"},
{"#": "19", "Unique ID": "100148", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 4 - Box 1 - Position 4", "Status": "Checked Out"},
{"#": "20", "Unique ID": "100149", "Name": "Book", "Section": "Paraguay", "Position": "Shelf 1 - Rack 5 - Box 1 - Position 1", "Status": "Available"}
]
// Dynamically get the entry headers to use with displaying the nested data via header-key lookups
// Assumes all lines contain same key-text data
$scope.samplePositionsHeaderKeys = []; // Contains only the key-data, not the values
for (var key in $scope.samplePositions[0]) {
if ($scope.samplePositions[0].hasOwnProperty(key)) {
$scope.samplePositionsHeaderKeys.push(key);
}
}
/**
* Determine if the input value is a number or not.
* @param n The input value to be checked for numeric status.
* @returns true if parameter is numeric, or false otherwise.
*
* This method uses the following evaluations to determine if input is a numeric:
*
* (5); // true
* ('123'); // true
* ('123abc'); // false
* ('q345'); // false
* (null); // false
* (""); // false
* ([]); // false
* (' '); // false
* (true); // false
* (false); // false
* (undefined); // false
* (new String('')); // false
*
* @author C.D. (modified by)
* @original https://stackoverflow.com/a/1421988/10930451
*
*/
function isNumeric(n) {
if (!isNaN(parseFloat(n)) && !isNaN(n - 0) && n !== null && n !== "") {
return true;
}
return false;
}
/**
* Column Sort Method (generic). Sort based on target column header or reverse sort if already selected on that.
* @param dataSource The array of JSON data to be sorted
* @param headers The array of JSON object-keys (table column headers) to be referenced
* @param index The target JSON object-key to sort the table columns based upon
*
* @author C.D.
*/
$scope.lastSortIndex = 0;
$scope.toggleSort = function (dataSource, headers, index) {
if ($scope.lastSortIndex === index) {
dataSource.reverse();
}
else {
var key = headers[index];
if (key === "#" || isNumeric(dataSource[key])) { // Compare as numeric or on '#' sign
dataSource.sort((a, b) => parseFloat(a[key]) - parseFloat(b[key]));
}
else // Compare as Strings
{
try { // Attempt to sort as Strings
dataSource.sort((a, b) => a[key].localeCompare(b[key]));
} catch (error) {
if (error.name === 'TypeError') { // Catch type error, actually sort as Numeric
dataSource.sort((a, b) => parseFloat(a[key]) - parseFloat(b[key]));
}
}
}
$scope.lastSortIndex = index;
}
}
});
AngularJS - Hello World
{{ header }}
{{row[key]}}
I have put together a working Plunker example to demonstrate. Just click on the headers and they will sort the array in memory, where AngularJS will pick up on the changes and refresh that portion of the DOM.