3

We have created an LWC which uses the LWC Component 'Lightning Datatable' component to display a table with dynamic columns & rows. We would like to apply dynamic styling of the rows based on its requiredness. For this purpose we have appended the columns with a 'cellAttributes' property pointing to a 'color' field which is dynamically added to each row in the frontend. The value in the 'color' property for each data row refers to standard SLDS styling as the Lightning Datatable, as per documentation, is unable to handle custom CSS.

This all works fine when the initial data you load has one or more rows of which the color property is populated, as shown in the following image: enter image description here

We have now noticed that in (at least) one particular scenario the styling is not applied. Namely, when the initial rows do not have the color styling property defined and you refresh the data with some rows who have the color property defined. Even though, the columns and rows are correctly defined for styling to be applied, the datatable doesn't render it. The example is shown below:

Data 1 (Columns have cellAttributes & color property is blank on all rows) enter image description here

Column: {"fieldName":"quantity__c","label":"Quantity","sortable":true,"sortFieldName":"quantity__c","type":"number","typeAttributes":null,"cellAttributes":{"class":{"fieldName":"color"}}}

Data: {"recordId":"a3T1q000000OnqiEAC","isSelectable":true,"isRequired":false,"color":"","id":"a3T1q000000OnqiEAC","product__c":"01t1v00000DNP4YAAX","required__c":false,"sort_order__c":10,"quantity__c":1,"quantity_type__c":"Fixed","quantity_rounding__c":null,"product_name__c":"EasyGo - GoVisibility","price__c":500}

Data 2 (Columns have cellAttributes & color property is populated on some rows) enter image description here

Column: {"fieldName":"quantity__c","label":"Quantity","sortable":true,"sortFieldName":"quantity__c","type":"number","typeAttributes":null,"cellAttributes":{"class":{"fieldName":"color"}}}

Data: {"recordId":"a3T1q000000OnpmEAC","isSelectable":true,"isRequired":true,"color":"slds-text-color_success slds-theme_shade","id":"a3T1q000000OnpmEAC","product__c":"01t1v00000ESXI1AAP","required__c":true,"sort_order__c":10,"quantity__c":1,"quantity_type__c":"Fixed","quantity_rounding__c":null,"product_name__c":"EasyGo","price__c":null}

The Data in the lightning datatable is refreshed from the parent component by calling a method on the child component. This child component is used by multiple different parent components through a single business process, so we are pretty confident there should not be anything wrong as the styling is applied in all the other instances. The only difference in this scenario is, instead of moving between flow screens with embedded lwc, we now refresh the data in a single flow screen. This would lead us to assume that the datatable is not able to rerender/render correctly bon row change so that the styling is correctly applied. We have tried encapsulating the lightning datatable component as well as the child component between tag to remove it from the DOM and add it again but this does result in styling to be applied.

Does anyone have any tricks to apply the styling in this scenario?

Kind Regards, Wesley V W

4
  • would it be possible to use code blocks instead of screenshots of your code?
    – Gilhil
    Nov 29, 2022 at 9:31
  • Just to make it clear, if initial data coming into the table satisfies the criteria to make the row red it works. However, if the initial data coming does not match, but then a subsequent refresh or update of that data does meet the criteria, the styling is not applied? Nov 29, 2022 at 10:22
  • @BryanAnderson that is correct and well summarized. Thanks Nov 30, 2022 at 7:15
  • @Gilhil done, thanks for the suggestion. Nov 30, 2022 at 7:16

1 Answer 1

3

Take a look at the sample I put together. Basically I am highlighting the first cell green on load, then, through a button click, I am highlighting the second cell below to green and then changing the first cell to red:

generateData.js <- Just to generate random data one time on connectedCallback

export default function generateData({ amountOfRecords }) {
    return [...Array(amountOfRecords)].map((_, index) => {
        return {
            name: `Name (${index})`,
            website: 'www.salesforce.com',
            amount: Math.floor(Math.random() * 100),
            phone: `${Math.floor(Math.random() * 9000000000) + 1000000000}`,
            closeAt: new Date(
                Date.now() + 86400000 * Math.ceil(Math.random() * 20)
            ),
        };
    });
}

app.js

import { LightningElement } from "lwc";
import generateData from './generateData';

const columns = [
    {
      label: 'Label',
      fieldName: 'name',
      cellAttributes: {
          class: {
              fieldName: `format`
          }
      }
    },
    { label: 'Website', fieldName: 'website', type: 'url' },
    { label: 'Phone', fieldName: 'phone', type: 'phone' },
    { label: 'Balance', fieldName: 'amount', type: 'currency' },
    { label: 'CloseAt', fieldName: 'closeAt', type: 'date' },
];

export default class App extends LightningElement {

  data = [];
  columns = columns;

  connectedCallback() {
      let data = generateData({ amountOfRecords: 5 });
      data.forEach(ele => {
          ele.format = ele.name == 'Name (0)' ? 'slds-text-color_error' : 'slds-text-color_success';
      });
      this.data = data;
  }

  changeData() {
    let newData = [...this.data];
    newData.forEach(ele => {
        ele.format = ele.name == 'Name (1)' ? 'slds-text-color_error' : 'slds-text-color_success';
    });
    this.data = newData;
  }
}

app.html

<template>
    <div class="app slds-p-around_x-large">


        <div style="height: 300px;">
            <lightning-datatable key-field="id" data={data} columns={columns}>
            </lightning-datatable>
        </div>
        <lightning-button variant="brand" label="Brand" title="Primary action" onclick={changeData}
            class="slds-m-left_x-small"></lightning-button>

    </div>
</template>

Before button click: enter image description here

After button click: enter image description here

You must log in to answer this question.

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