5

I want to add attributes or classes for rows/cells in lightning:datatable based on cell values (I want to customize styles based on values). Is it possible? How can this be achieved?

P.S. I tried to use document.querySelectorAll, document.getElementsByClassName, etc. in 'render' event handler and in custom renderer to find rows and cells but these methods always return empty list/null. Is it due to Locker Service?

My component markup:

<aura:component implements="force:appHostable">

    <aura:attribute name="objectList" type="List"/>
    <aura:attribute name="objectColumns" type="List"/>

    <aura:handler name="init" value="{!this}" action="{!c.onInit}"/>

    <lightning:datatable data="{!v.objectList}"
                         columns="{!v.objectColumns}"
                         keyField="id"/>

</aura:component>

My component controller:

        ({
        onInit: function (cmp, event, helper) {
            cmp.set('v.objectColumns', [
                {label: 'Name', fieldName: 'name', type: 'text', sortable: true},
                {label: 'Status', fieldName: 'status', type: 'text', sortable: true}
            ]);

            cmp.set('v.objectList', [
                {id: '1', name: 'object one', status: 'Active'},
                {id: '2', name: 'object two', status: 'Inactive'},
            ]);
        }
        })

I want to assign rows with active and inactive statuses with different css classes.

4
  • Yes, this is due to locker service. have you tried anything using the components Attributes and events available in the framework? A good place to start would be theLightning Components Developer Guide
    – glls
    Commented Feb 19, 2018 at 20:08
  • @glls thanks for reply! Is there any specific attribute or event I should look at? It looks like it is not possible to add styles the way I'm used to (find nodes and then add classes to them) but maybe there is another approach in lightning?
    – user39399
    Commented Feb 19, 2018 at 20:26
  • there are different approaches, for example, from the components markup you can conditionally instantiate and render your DOM with the classes you want based on the value of x attribute. Another approach would be by creating a custom Renderer. I would suggest you look it up and try either way. Once you have some code sample working and are stuck somewhere, please update your post.
    – glls
    Commented Feb 19, 2018 at 20:32
  • @glls added code sample. I understand what a custom renderer is, but how exactly can I find rows with it? I was going to use it for DOM search and edit but the search doesn't work so I can't obtain the nodes to edit them.
    – user39399
    Commented Feb 19, 2018 at 20:57

2 Answers 2

9

As others have mentioned, the LockerService means you can't attack the problem via the DOM, but instead have to see what the component offers.

I followed the lightning:datatable JavaScript through in the debugger and found that the cellAttributes mechanism documented to support this:

{  
    label:'Confidence',
    fieldName:'confidence',
    type:'percent',
    cellAttributes:{  
        iconName:{  
            fieldName:'trendIcon'
        },
        iconPosition:'right'
    }
}

will also allow this:

{  
    label:'Name',
    fieldName:'Name',
    type:'text',
    cellAttributes:{  
        class:{  
            fieldName:"ClassName__c"
        }
    }
},

and set the DOM attribute class to the value of the field specified, be that a fixed value or a reference to a row field (as illustrated here).

Note too that the fieldName does not have to be an actual field in the SObject. In my case I have JavaScript code that works out the CSS class from other data values and adds that to the row:

// Convert to style
for (i = 0; i < data.length; i++) {
    var row = data[i];
    row._class = ...;
}

and then set fieldName:"_class".

As a not documented feature it cannot necessarily be relied on, but seems like a valuable mechanism so I hope it will make it into the documentation and so become "official API".

4
  • Great thanks for sharing your solution! It works perfectly for setting classes for cells. Do you know if there's also a way to add classes to rows?
    – user39399
    Commented Apr 16, 2018 at 17:01
  • 1
    @user39399 I don’t think there is.
    – Keith C
    Commented Apr 16, 2018 at 17:03
  • I have done this and my cell is getting the class: <td role="gridcell" tabindex="-1" data-label="Type" class="error"> but the color is not getting applied. CSS: .THIS .error { color: red;}. Any thoughts?
    – Shanerk
    Commented Dec 16, 2020 at 20:59
  • Inspect the content of the page to see what the CSS name is transformed to and use that name? (Sorry I don't have my example any more.)
    – Keith C
    Commented Dec 17, 2020 at 8:18
2

I was looking for the same answer and google led me down this path. After a little more research I discovered that the accepted answer here is outdated.

Keith C's answer will work and is now documented and supported (See section 'Adding Styles to Columns').

However it appears that the functionality Keith is leveraging is intended to provide row level styling support. Use the cellAttributes.class.fieldname for each column in your datatable and then vary the value of that field on each row to add individual styles to rows.

var columns = [
 { label: 'Opportunity name', fieldName: 'opportunityName', type: 'text', 
     cellAttributes:
         { class: { fieldName: 'aFieldInYourData' }}
 }, // other column data
];

To add style to a column simply populate the cellattribute.class property with the string value of your custom style class

var columns = [
 { label: 'Account Name', fieldName: 'Name', 
     cellAttributes: 
         { class: 'customCSSClass'}
 },  // other column data     
];

and make sure you have your custom style defined in your component.css file (Style)

.THIS .customCSSClass {
 color: blue;
}

You must log in to answer this question.

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