7
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

1 Answer 1

14

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);
    }
})
9
  • Thanks for the reply, I didn't frame my question correctly I use offset over multiple pages is there anyway that I could limit number of records on each page with in the JavaScript?
    – cartman
    Commented Nov 24, 2016 at 17:49
  • @cartman aura:iteration doesn't support things like limit/offset, but you could load all of the records into a single variable, then call Array.slice to pull out some of those records into a separate list; you can then iterate over those. The event handlers for next, prev, first, last, etc would simply slice out a chunk of the main record array for display purposes. Sorting, of course, would occur on the master record list, as demonstrated here.
    – sfdcfox
    Commented Nov 24, 2016 at 18:42
  • 2
    @cartman I wrote a gist that demonstrates pagination + sorting client-side. Does this help you?
    – sfdcfox
    Commented Nov 24, 2016 at 21:22
  • @sfdcfox Great gist! Helped me a lot in a sorting and pagination solution that I needed! Although the direct link doesn't work anymore. But you can still find it easy enough.
    – JRiffe
    Commented Jun 22, 2017 at 20:24
  • Hello @sfdcfox, your solution works. However, I was trying to create a sorting function and pass that function to the .sort method like this: records.sort(this.mySortingFunction) (the mySortingFunction and the records sorting are both in the helper). Is there a way to do this? Or is the inline sorting the only thing that works?
    – SamuelDev
    Commented May 10, 2018 at 22:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .