Build a Lightning Component Data Table using SLDS

Thinking of building some lightning components and want to style them to fit in with the lightning ui – then read on! Even if you are not using the lightning yet, this component looks pretty good in the classic ui too. I have built this using the Salesforce Lightning Design System (SLDS) which allows you to use css that fits right in with the salesforce ui.

Currently there is no equivalent of the datatable component that is available in visualforce for lightning components – this is rumoured to be coming in the Spring 17 release but this post will help you create data tables before then. I have split the code in the different sections and explained each piece of code. There is also a link to the complete code in github at the bottom of the post.

I have build this example which displays a simple list of contacts that are related to the account. In the screen shot below, I have added the component to the lightning account page to show the list of contacts beside the account details.

screen-shot-2016-11-30-at-19-12-02

The first step is to create the table using the css from the lightning design system. I use this in conjunction with the aura:iteration (the lightning equivalent of apex:repeat) to build the table header and rows.

 

        <table class="slds-table slds-table--bordered slds-table--cell-buffer">
            <thead>
                <tr class="slds-text-title--caps">
                    <th scope="col">
                        <div class="slds-truncate" title="First Name">First Name</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Last Name">Last Name</div>
                    </th>
                    <th scope="col">
                        <div class="slds-truncate" title="Email">Email</div>
                    </th>
                </tr>
            </thead>
            <tbody>
                <aura:iteration items="{!v.contactList}" var="ct">
                    <tr>
                        <th scope="row" data-label="First Name">
                            <div class="slds-truncate" title="{! ct.FirstName }">{! ct.FirstName }</div>
                        </th>
                        <td data-label="Last Name">
                            <div class="slds-truncate" title="{! ct.LastName }">{! ct.LastName }</div>
                        </td>
                        <td data-label="Email">
                            <div class="slds-truncate" title="{! ct.Email }">{! ct.Email }</div>
                        </td>
                    </tr>
                </aura:iteration>
            </tbody>
        </table>

This will display the basic table we will need to add a controller to populate the data table. The code below will add the apex controller to get the data to display in the table. The table slots in before the closing of the aura:component (the full code is linked in github at the bottom of this post).

 
<aura:component controller="AccountContactData" implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global" >
    <aura:attribute name="contactList" type="Object" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
</aura:component>

init is a method in the javascript controller that will run as when the component initialises (its a standard method).
force:hasRecordId takes the current records id and uses it has the id – this is how it automatically works when placed on the account page as it knows the account id.
The attribute is simply a list to hold all of the contacts that I want to display.

If you would like the exact styling that I have used you will need to wrap the table in the following tag

 
<lightning:card iconName="utility:user" title="Contacts">

// all of the table code goes in here

</lightning:card>

The next step is to create the apex controller (note – you will get an error when saving if the controller does not exist). The apex controller (you will see later on why I call it the apex controller instead of the just a controller!). This simple returns the contacts related to the account using the account id. The only difference between this and a visualforce controller is that @AuraEnabled tag.

 
public class AccountContactData {

	@AuraEnabled
    public static List<Contact> getAccountContacts (Id recordId) {  

        List<Contact> contacts = [SELECT FirstName, LastName, Email FROM Contact WHERE AccountId=:recordId];

        return contacts;
    }
}

After this, we want to link our lightning component (the visual part) and the apex controller (logic to get our data from the database). When building lightning components, this is done using the javascript controller – you will notice that is automatically created when you create the lightning component.
In here, I have created the doInit function which we declared at the top of our lightning component in the aura:handler

 
({
	doInit : function(component, event, helper) {
		var recID = component.get("v.recordId");
        var action = component.get("c.getAccountContacts");
        action.setParams({
            recordId: recID
        });
        action.setCallback(this, function(response){
            var data = response.getReturnValue();
            component.set("v.contactList", data);
        });
        $A.enqueueAction(action);
	}
})

This gets our record id so we can pass it to the apex controller (“v.” denotes its getting it from the component for view).
We also need to call and pass parameters to our apex controller (“c.” denotes that we are using the apex controller). We call our apex method, set the parameters. We use the standard method called getReturnValue() to the data returned from the apex controller. We then use the component.set() to the pass the data back to the component or view.
$A.enqueueAction(action) simply queues our action for execution – it will happen straight away if there is only one action but we could queue multiple actions.

Putting all of this together gives us our lightning data table that we can slot in to the account page in lightning.
If you are still using classic, you can still you use the same component but you will need to pass the account id in to the component which could be done in many ways e.g. embedding the lightning component inside a visualforce page.

The code for the full solution is available in the github repository linked below:
https://github.com/paddybutler/Lightning-Component-Data-Table

Leave a Reply