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

13

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);
    }
})
  • 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 Nov 24 '16 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 Nov 24 '16 at 18:42
  • 2
    @cartman I wrote a gist that demonstrates pagination + sorting client-side. Does this help you? – sfdcfox Nov 24 '16 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 Jun 22 '17 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 May 10 '18 at 22:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.