[SalesForce] LWC Datatable with custom data type not rendering as supose

I have formula fields that show HTML values and I need to show them in a custom related record data table

enter image description here

What I have tried so far.

And to be honest, I'm frustrated right now because it's not working for me, maybe I'm tired and I don't see the issue or something, but I feel like I have tried everything.

Parent Component –

HTML

<template>
    <lightning-card icon-name={iconName} title={objectLabel}>
        <c-rich-datatable key-field="Id" data={tableData} columns={tableColumns} hide-checkbox-column
                      wrap-text-max-lines="3"></c-rich-datatable>
    </lightning-card>
</template>

JS

import { LightningElement, api, wire, track} from 'lwc';
import getIconName from '@salesforce/apex/ICRM_DynamicRelatedRecordsList_Ctrlr.getIconName';
import getObjectLabel from '@salesforce/apex/ICRM_DynamicRelatedRecordsList_Ctrlr.getObjectLabel';
import getFieldSet from '@salesforce/apex/ICRM_DynamicRelatedRecordsList_Ctrlr.getFieldSet';

export default class IcrmDrrl extends LightningElement {
    @api recordId;
    @api objectName = '';
    @api relatedField = '';
    @api fieldList = '';
    @api recordsToDisplay = 0;
    @track iconName = '';
    @track objectLabel = '';
    @track tableData = [];
    @track tableColumns = [];
    @track result = [];

    @wire(getIconName, { objectName: '$objectName' })
     wiredIcon({ error, data}) {
         if(data) {
            this.iconName = data;
         } else if (error) {
            this.error = error;
            this.iconName = undefined;
         }
     }

    @wire(getObjectLabel, { sobjectApiName: '$objectName' })
    wiredLabel({ error, data}) {
        if(data) {
            this.objectLabel = data;
        } else if (error) {
            this.error = error;
            this.objectLabel = undefined;
        }
    }

    @wire(getFieldSet, {
        sObjectName: '$objectName',
        listOfFields: '$fieldList',
        recordId: '$recordId',
        relationshipField: '$relatedField',
        recordsToDisplay: '$recordsToDisplay'
    }) wiredResults({error, data}) {
        if (data) {
            this.tableData = data.listData;
            this.result = data.columns;
        } else if (error) {
            this.error = error;
            this.tableData = undefined;
            this.result = undefined;
        }
    }

    connectedCallback() {
        this.result.map((col) => {
            return (col.type = "richText");
        });
        console.log(JSON.stringify(this.result));
        this.tableColumns = this.result;
        console.log(JSON.stringify(this.tableColumns));
    }

}

CustomDatatable component

HTML

<template>
</template>

JS

import LightningDatatable from "lightning/datatable";
import richTextColumnType from "./richTextColumnType.html";

/**
 * Custom component that extends LightningDatatable
 * and adds a new column type
 */
export default class richDatatable extends LightningDatatable {
    static customTypes = {
        // custom type definition
        richtext: {
            template: richTextColumnType,
            standardCellLayout: true
        }
    }
}

HTML template for customDatatable

<template>
    <!-- a template for cell. File in the myCustomDatatable directory -->
    <template if:true={wrapText}>
        <lightning-formatted-rich-text value={value} class="slds-truncate">
        </lightning-formatted-rich-text>
    </template>
    <template if:false={wrapText}>
        <lightning-formatted-rich-text value={value}>
        </lightning-formatted-rich-text>
    </template>
</template>

And still can't make it work.

Thanks in advance to sfdcfox for helping me with the last issue.

Thanks.

Best Answer

You're probably missing out type attribute in the columns for the formula field. Since it's a formula-text field. The default text column is applied.

You need to add a type attribute to the columns for that field that should be like,

  columns = [
    // standard text column
    { label: "Text Column", fieldName: "textCol", wrapText: true },
    {
      label: "Text Column",
      fieldName: "richField",
      type: "richText",
      wrapText: true,
    },
    {
      label: "Rich Text",
      fieldName: "richTextCol__c",
      type: "richText", //specify a type attribute here 
      wrapText: true,
    },
  ];

You can see a live demo here.

enter image description here

Once you get columns from apex. You need to change the type attribute before assigning it to the columns attribute.

  connectedCallback() {
    result.map((col) => {
      if (col.fieldName === YOUR_RICH_TEXT_FIELD) {
        return (col.type = "richText");
      }
    });
   this.columns = result;
  }

Apex Class

public with sharing class ICRM_DynamicRelatedRecordsList_Ctrlr {

    @AuraEnabled (Cacheable= true)
    public static String getIconName(String objectName) {
        String u;
        List<Schema.DescribeTabSetResult> tabSetDesc = Schema.describeTabs();
        List<Schema.DescribeTabResult> tabDesc = new List<Schema.DescribeTabResult>();
        List<Schema.DescribeIconResult> iconDesc = new List<Schema.DescribeIconResult>();

        for (Schema.DescribeTabSetResult tsr : tabSetDesc) {
            tabDesc.addAll(tsr.getTabs());
        }

        for (Schema.DescribeTabResult tr : tabDesc) {
            if (objectName == tr.getSobjectName()) {
                if (tr.isCustom() == true) {
                    iconDesc.addAll(tr.getIcons());
                } else {
                    u = 'standard:' + objectName.toLowerCase();
                }
            }
        }
        for (Schema.DescribeIconResult ir : iconDesc) {
            if (ir.getContentType() == 'image/svg+xml') {
                u = 'custom:' + ir.getUrl().substringBetween('custom/', '.svg').substringBefore('_');
                break;
            }
        }
        return u;
    }

    @AuraEnabled (Cacheable= true)
    public static String getObjectLabel(String sobjectApiName) {
        Schema.SObjectType sobjectType = Schema.getGlobalDescribe().get(sobjectApiName);
        Schema.DescribeSObjectResult sobjectDescribe = sobjectType.getDescribe();
        return sobjectDescribe.getLabelPlural();
    }

    @AuraEnabled (Cacheable= true)
    public static ColumnAndDataWrapper getFieldSet(String sObjectName, String listOfFields, Id recordId, String relationshipField, Integer recordsToDisplay) {
        ColumnAndDataWrapper cdw = new ColumnAndDataWrapper();
        List<Columns> columns = new List<Columns>();
        String fieldsToFetch = '';

        Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
        Schema.SObjectType ctype = gd.get(sObjectName);
        Map<String, Schema.SObjectField> fmap = ctype.getDescribe().fields.getMap();

        List<String> fieldList = listOfFields.replaceAll(' ','').split(',');

        // Generating a list of columns
        for (String f : fieldList) {
            if (f == 'Name') {
                // Uncomment and replace to allow go to record by clicking name
                // columns.add(new Columns(fmap.get(f).getDescribe().getLabel(), 'linkName', 'url'));
                columns.add(new Columns(fmap.get(f).getDescribe().getLabel(), 'Name', 'text'));
            } else {
                columns.add(new Columns(fmap.get(f).getDescribe().getLabel(), f, String.valueOf(fmap.get(f).getDescribe().getType()).toLowerCase()));
            }
            if (fieldsToFetch != '') {
                fieldsToFetch += ',';
            }
            fieldsToFetch += f;
        }

        // Get the records of requested object
        List<SObject> listData;
        if (recordsToDisplay == null) {
            listData = Database.query('SELECT Id, ' + fieldsToFetch + ' FROM ' + sObjectName + ' WHERE ' + relationshipField + ' = :recordId ');
        } else if (recordsToDisplay != null && recordsToDisplay > 0) {
            listData = Database.query('SELECT Id, ' + fieldsToFetch + ' FROM ' + sObjectName + ' WHERE ' + relationshipField + ' = :recordId LIMIT ' + recordsToDisplay);
        }
        cdw.columns = columns;
        cdw.listData = listData;
        return cdw;
    }

    public class Columns {
        @AuraEnabled public String label;
        @AuraEnabled public String fieldName;
        @AuraEnabled public String type;
        public Columns(String label, String fieldName, String type) {
            this.label = label;
            this.fieldName = fieldName;
            this.type = type;
        }
    }

    public class ColumnAndDataWrapper {
        @AuraEnabled public List<Columns> columns;
        @AuraEnabled public List<SObject> listData;
    }

}
Related Topic