9

I'm trying to implement the sorting functionality on a lightning:datatable. Sorting works one way (descending, clicking the column header again and nothing happens). I have followed the documentation and here's my code below:

<aura:attribute name="selectedAccountId" type="Id" access="public" />
<aura:attribute name="accounts" type="Object"/>
<aura:attribute name="mycolumns" type="List"/>
<aura:handler name="init" value="{! this }" action="{! c.doInit }"/>

<aura:registerEvent name="AccountFilterChange" type="c:AccountFilterChange" />


<lightning:datatable aura:id="lightningTable"
                     data="{! v.accounts }"
                     columns="{! v.mycolumns }"
                     keyField="Id"
                     onrowaction="{! c.handleRowAction }"
                     onsort="{!c.updateColumnSorting}"
                     hideCheckboxColumn="true"
/>

Controller:

doInit: function(component, event, helper) {
   helper.callServer(component, "c.getAccounts", function(response) {
       component.set("v.accounts", response);
       })
    component.set('v.mycolumns', [
        {type: "button", typeAttributes: {
            label: '',
            iconName: 'utility:add',
            name: 'selectRecord',
            title: 'selectRecord',
            disabled: false,
            value: 'edit',
            variant: {fieldName: 'variantValue'},
        }},
        {label: 'Name', fieldName: 'Name', type: 'text', sortable: true},
            ]);
        },

handleRowAction: function(component, event, helper) {
    var account = event.getParam("row")
    var action = event.getParam("action");
    if (action.name == "selectRecord") {
        var event = component.getEvent("AccountFilterChange");
         event.setParams({
            accountId: account.Id,
        });
    }
 event.fire();
 helper.addRow(component, account);
},

updateColumnSorting: function(component, event, helper) {
    var fieldName = event.getParam('fieldName');
    var sortDirection = event.getParam('sortDirection');
    // assign the latest attribute with the sorted column fieldName and sorted direction
    component.set("v.sortedBy", fieldName);
    component.set("v.sortedDirection", sortDirection);
    helper.sortData(component, fieldName, sortDirection);
    }

Helper:

sortData: function (component, fieldName, sortDirection) {
     var data = component.get("v.accounts");
     var reverse = sortDirection !== 'asc';
     //sorts the rows based on the column header that's clicked
     data.sort(this.sortBy(fieldName, reverse))
     component.set("v.accounts", data);
     },
 sortBy: function (field, reverse, primer) {
     var key = primer ? function(x) {return primer(x[field])} : function(x) {return x[field]};
     //checks if the two rows should switch places
     reverse = !reverse ? 1 : -1;
     return function (a, b) {
         return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
     }
 }

How would I make this work so both desc/asc will work when clicking the column header?

19

One bit the documentation omits is that in order to get sorting to work, you have to bind a couple of extra attributes to the lightning:datatable. I've discovered this before quite by accident.

Component/Application

<aura:attribute name="sortedBy"
                type="String" />
<aura:attribute name="sortedDirection"
                type="Boolean"
                default="true" />

...

<lightning:datatable ...                          
                     sortedBy="{!v.sortedBy}"
                     sortedDirection="{!v.sortedDirection}" />

Then, in your sortData function:

    component.set("v.sortedBy", event.getParam("fieldName"));
    component.set("v.sortedDirection", event.getParam("sortDirection"));

Once you do this, the rest of the code from the documentation should work as expected.

| improve this answer | |

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.