Friday, July 5, 2019

Lightning Data table with sorting in Lightning Web Component(lwc)

This post explains how to sort the lightning data table data in lightning web components(lwc)



Example:
HTML Code
<template>
    <lightning-card title="Sorting Data in Lightning Datatable in LWC" icon-name="standard:contact" > <br/>
        <div style="width: auto;">
            <template if:true={data}>
                <lightning-datatable data={data}
                                     columns={columns}
                                     key-field="id"
                                     sorted-by={sortBy}
                                     sorted-direction={sortDirection}
                                     onsort={handleSortdata}
                                     hide-checkbox-column="true"></lightning-datatable>
            </template>

        </div>
    </lightning-card>
</template>
Javascript Controller Code
import {LightningElement, wire, track} from 'lwc';

// importing apex class methods
import getContacts from '@salesforce/apex/LWCExampleController.getContacts';

// datatable columns with row actions
const columns = [
    {
        label: 'FirstName',
        fieldName: 'FirstName',
        sortable: "true"
    }, {
        label: 'LastName',
        fieldName: 'LastName',
        sortable: "true"
    }, {
        label: 'Phone',
        fieldName: 'Phone',
        type: 'phone',
        sortable: "true"
    }, {
        label: 'Email',
        fieldName: 'Email',
        type: 'email'
    },
];

export default class DataTableWithSortingInLWC extends LightningElement { 
    // reactive variable
    @track data;
    @track columns = columns;
    @track sortBy;
    @track sortDirection;

    // retrieving the data using wire service
    @wire(getContacts)
    contacts(result) {
        if (result.data) {
            this.data = result.data;
            this.error = undefined;

        } else if (result.error) {
            this.error = result.error;
            this.data = undefined;
        }
    }

    handleSortdata(event) {
        // field name
        this.sortBy = event.detail.fieldName;

        // sort direction
        this.sortDirection = event.detail.sortDirection;

        // calling sortdata function to sort the data based on direction and selected field
        this.sortData(event.detail.fieldName, event.detail.sortDirection);
    }

    sortData(fieldname, direction) {
        // serialize the data before calling sort function
        let parseData = JSON.parse(JSON.stringify(this.data));

        // Return the value stored in the field
        let keyValue = (a) => {
            return a[fieldname];
        };

        // cheking reverse direction 
        let isReverse = direction === 'asc' ? 1: -1;

        // sorting data 
        parseData.sort((x, y) => {
            x = keyValue(x) ? keyValue(x) : ''; // handling null values
            y = keyValue(y) ? keyValue(y) : '';

            // sorting values based on direction
            return isReverse * ((x > y) - (y > x));
        });

        // set the sorted data to data table data
        this.data = parseData;

    }

}
Configuration XML File

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="dataTableWithSortingInLWC">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>
Apex Class
public inherited sharing class LWCExampleController {
    
    @AuraEnabled(Cacheable = true)
    public static List<Contact> getContacts(){
        return [SELECT Id, FirstName,LastName, Phone, Email FROM Contact limit 15];
    }
}
Result

6 comments:

  1. Thanks so much -- this is exactly what I needed!

    ReplyDelete
  2. Exactly what was needed. Thank you!

    ReplyDelete
  3. A little explanation of flow please?

    ReplyDelete
  4. I am looking for name as link and columns like below,
    const columns = [
    {
    label: 'CName',
    fieldName: 'nameUrl',
    type: 'url',
    typeAttributes: {label: { fieldName: 'Name' },
    target: '_blank'},
    sortable: true
    }, {
    label: 'Identity',
    fieldName: 'Id',
    sortable: true
    }
    ];

    and i changed the .js file like below,but not able to get the link with sorting
    if (data) {
    let nameUrl;
    this.contacts= data.map(row => {
    nameUrl = `/${row.Id}`;

    return {...row , nameUrl}
    })

    ReplyDelete
  5. is there any way to permanent show the sorting arrow in header ?

    ReplyDelete