1

Note - I followed the approach from this link - How to make columns lwc lightning-datatable dynamic with button-icon

I am trying to build a data table like below:

enter image description here

The column has dates which is start of the week(Sunday) of a month. Example in July - 10,17,24,31 and 7th. I calculate the date using the apex class. In the apex wrapper.

I am not sure how I can use a single column to populate all the dates from apex. And also I need the ability to move the dates forward to next week when NEXT button on the top is clicked.

What I tried in Apex controller is to build a wrapper and logic to calculate dates:

public class ContactWrapper{ 
    @AuraEnabled
    public String FirstName; 
    @AuraEnabled
    public Date weekStartDate;  
} 

@AuraEnabled(cacheable=true)
public static List<ContactWrapper> buildWrapper(){
    List<ContactWrapper> result = new List<ContactWrapper>();
    List<Contact> conList = getContactList();
    integer j = 0;
    for(integer i =0;i<4;i++){
        ContactWrapper wrpObj = new ContactWrapper();
        wrpObj.FirstName = conList[i].FirstName;
        wrpObj.weekStartDate = Date.today().toStartofWeek().addDays(j);
        j = j + 7;
        result.add(wrpObj);
    } 

    return result;
}

ThE JS:

import { LightningElement, wire } from 'lwc';
import buildWrapper from '@salesforce/apex/ContactController.buildWrapper';

const COLS = [
    { label: 'First Name', fieldName: 'FirstName' },
];
export default class DatatableCustomDataType extends LightningElement {
    columns = COLS;
    contacts;

    @wire(buildWrapper)
     wiredContacts(result){
         console.log('result---> ' + JSON.stringify(result.data));
 if (result.data) {
    this.columns = [...this.columns, ...result.data.weekStartDate];
 }
    }

}

HTML:

<template>
    <lightning-card
        title="Datatable Custom Data Type"
        icon-name="custom:custom62"
    >
    <lightning-button variant="brand" label="Go Next" title="Primary action" onclick={handleClick} class="slds-m-left_x-small"></lightning-button>
        <div class="slds-var-m-around_medium">

            <template if:true={contacts}>
                <c-custom-data-types
                    key-field="Id"
                    data={contacts}
                    columns={columns}
                    hide-checkbox-column="true"
                >
                </c-custom-data-types>
            </template>
        </div>

    </lightning-card>
</template>

How can I dynamically change the columns from what is returned from the apex wrapper:

const COLS = [
    { label: 'First Name', fieldName: 'FirstName' },
    // the dates july 10, Juy 17, July 24 and July 31 should dynamically build.
];

Apex Class:

public with sharing class ContactController {
    @AuraEnabled(cacheable=true)
    public static List<Contact> getContactList() {
        return [
            SELECT
                Id,
                Name,
                FirstName,
                LastName,
                Title,
                Phone,
                Email,
                Picture__c
            FROM Contact
            WHERE Picture__c != NULL
            WITH SECURITY_ENFORCED
            LIMIT 10
        ];
    }

    @AuraEnabled(cacheable=true)
    public static List<Contact> findContacts(String searchKey) {
        String key = '%' + searchKey + '%';
        return [
            SELECT Id, Name, Title, Phone, Email, Picture__c
            FROM Contact
            WHERE Name LIKE :key AND Picture__c != NULL
            WITH SECURITY_ENFORCED
            LIMIT 10
        ];
    }

    @AuraEnabled(cacheable=true)
    public static Contact getSingleContact() {
        return [
            SELECT Id, Name, Title, Phone, Email, Picture__c
            FROM Contact
            WITH SECURITY_ENFORCED
            LIMIT 1
        ];
    }

    @AuraEnabled
    public static void updateContacts(List<Contact> contactsForUpdate) {
        // Make sure we can update the database before trying to update
        if (!Schema.sObjectType.Contact.isUpdateable()) {
            throw new SecurityException(
                'Insufficient permissions to update contacts'
            );
        }
        update contactsForUpdate;
    }

    public class ContactWrapper{ 
        @AuraEnabled
        public String FirstName; 
        @AuraEnabled
        public Date weekStartDate;  
    } 

    @AuraEnabled(cacheable=true)
    public static List<ContactWrapper> buildWrapper(){
        List<ContactWrapper> result = new List<ContactWrapper>();
        List<Contact> conList = getContactList();
        integer j = 0;
        for(integer i =0;i<4;i++){
            ContactWrapper wrpObj = new ContactWrapper();
            wrpObj.FirstName = conList[i].FirstName;
            wrpObj.weekStartDate = Date.today().toStartofWeek().addDays(j);
            j = j + 7;
            result.add(wrpObj);
        } 

        return result;
    }
}

Anything I can refer to implement this? Please let me know.

My code base is based on lwc-receipe - https://github.com/trailheadapps/lwc-recipes/blob/main/force-app/main/default/lwc/datatableCustomDataType/datatableCustomDataType.html

1 Answer 1

1

As it will be a very long answer to write in full, I will try to explain the approach I have in my mind. There are two parts you need to do.

A: Columns You need to get the weekStartDate from the apex and then you can build all 7 columns in the lwc or apex controller in this format.

[{
    fieldName: 'day_1',
    label: 'Aug 01',
    type: 'yourCustomType'
},
// ...
{
    fieldName: 'day_7',
    label: 'Aug 07',
    type: 'yourCustomType'
}]

For this, you can run a for loop to generate the above list and use date format methods from apex/js to format the column label as per your need.

B: Data You need to format data in such a way that one row contains data for one week. like:

[
    {
        day_1: 'value 1',
        day_2: 'value 2',
        //...
        day_7: 'value 7',
        
        // add additional fields if needed.
    },
    {
        day_1: 'value 1',
        day_2: 'value 2',
        //...
        day_7: 'value 7',
        
        // add additional fields if needed.
    },
    {
        day_1: 'value 1',
        day_2: 'value 2',
        //...
        day_7: 'value 7',
        
        // add additional fields if needed.
    },

    // ...

]

You can create a wrapper class to store the data in apex like this.

public class WeekDataWrapper{
    @AuraEnabled
    public DataType day_1;
    @AuraEnabled
    public DataType day_2;
    //...
    
    @AuraEnabled
    public DataType day_7;
}

Please note that I am suggesting generic names for fields instead of dates so that you can do the pagination easily. Also, you can use the apex map if the number of days is dynamic.

Use the below type instead of the wrapper to store data if you want to keep a number of columns dynamic.

List<Map<String>, Object>> getData(){}

where the keys will be the day example day_1 to day_N, and the value will be the data you want to display. You can return this list of maps as it is and JS will automatically convert that to a list of objects very similar to the wrapper format provided above.

You can refer to this post for datatable pagination.

I hope this is helpful!

You must log in to answer this question.

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