Edit
Here's an updated link for the code provided below.
In Lightning, there's no need to import a library or call out to the server, you can just write your own. Note: I've not tested this, so you may need to tweak it to suit your needs.
({
sortByName: function(component, event, helper) {
var currentOrder = component.get("v.sortAsc"),
currentList = component.get("v.records");
currentOrder = !currentOrder;
currentList.sort(function(a,b) {
var t1 = a.Name == b.Name, t2 = a.Name < b.Name;
return t1? 0: (currentOrder?-1:1)*(t2?1:-1);
});
component.set("v.sortAsc", currentOrder);
component.set("v.records", currentList);
}
})
Your actual click handler needs a minor adjustment as well:
onclick="{!c.sortByName}"
This code assumes two variables, namely sortAsc, a Boolean, and records, a list of Opportunity records.
To make it more palatable for multiple fields to sort by, you'll want to put this logic into a helper function, then you can replace all the .Name references with a dynamic attribute, like a[field] < b[field]
.
I actually wrote a demo for this. It's not "pretty", but it demonstrates the functionality:
OpportunityHelper.cls
public class OpportunityHelper {
@AuraEnabled public static Opportunity[] loadOpportunityRecords() {
return [SELECT Name, Amount FROM Opportunity WHERE Amount <> NULL LIMIT 10];
}
}
opportunity.app
<aura:application controller="OpportunityHelper">
<aura:attribute type="Opportunity[]" name="records" />
<aura:attribute type="Boolean" name="sortAsc" />
<aura:attribute type="String" name="sortField" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<table>
<thead>
<td onclick="{!c.sortByName}">Name</td>
<td onclick="{!c.sortByAmount}">Amount</td>
</thead>
<tbody>
<aura:iteration items="{!v.records}" var="record">
<tr>
<td>{!record.Name}</td>
<td>{!record.Amount}</td>
</tr>
</aura:iteration>
</tbody>
</table>
</aura:application>
opportunityController.js
({
doInit: function(component, event, helper) {
var load = component.get("c.loadOpportunityRecords");
load.setCallback(this, function(result) {
component.set("v.records", result.getReturnValue());
component.set("v.sortAsc", true);
helper.sortBy(component, "Name");
});
$A.enqueueAction(load);
},
sortByName: function(component, event, helper) {
helper.sortBy(component, "Name");
},
sortByAmount: function(component, event, helper) {
helper.sortBy(component, "Amount");
}
})
opportunityHelper.js
({
sortBy: function(component, field) {
var sortAsc = component.get("v.sortAsc"),
sortField = component.get("v.sortField"),
records = component.get("v.records");
sortAsc = field == sortField? !sortAsc: true;
records.sort(function(a,b){
var t1 = a[field] == b[field],
t2 = a[field] > b[field];
return t1? 0: (sortAsc?-1:1)*(t2?-1:1);
});
component.set("v.sortAsc", sortAsc);
component.set("v.sortField", field);
component.set("v.records", records);
}
})