[SalesForce] Lightning client side sorting

component.set("v.Accounts", Accounts);

has the accounts that I need.

<th scope="col">
        <div class="slds-truncate" title="Opportunity Name" onclick"{!sortbyOpportunityNAme}">Opportunity Name</div>
      </th>

I was wondering if there is anyway that I could sort the results on the client side instead of making server calls on click of the column

Best Answer

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);
    }
})