1

I have a list of an object that i show in a lightning-datatable that has some duplicate values in the first column, like this:

enter image description here

Apex:

@AuraEnabled(cacheable=true) 
 public static List<Asset> getAsset(Id recordId) {
     return [SELECT Id,Name,Product_Family__c,Type__c FROM Asset WHERE License__c =:recordId];
 }

js:

@wire(getAsset, { recordId: '$recordId'})
getAsset({data, error}) {
    if(data) {
        this.assetsList = JSON.parse(JSON.stringify(data));
        this.error = undefined;
    }
    else if (error) {
        this.showError(error);
        this.assetsList = undefined;
    }
}

html:

 <lightning-datatable
            key-field="id"
            data={assetTest}
            hide-checkbox-column="true"
            columns={columns}>
 </lightning-datatable>

I want to be able to merge the duplicate values from the first row and show it like this:

enter image description here

How can i do this using datatable? and if not with datatable, is there another way to do this?

1

As of now, there is no option to achieve this using the standard lightning-datatable component. But you can achieve the same using a custom table and SLDS. You will need to prepare your data in such a way that all other rows are grouped up basis Product Family.

Based on number rows in each Product family you can define the row span in td attribute of Table.

I have created a sample table in this playground.

So whenever data is returned from the apex/wired method you need to process it and group basis product family. See the below code. I have used a simple hardcoded products list to demonstrate the example.

   get productArray() {
       let samples = [
           {
               family: 'Family 1',
               assetName: 'Name 1',
               assetType: 'Type 1'
           },
           {
               family: 'Family 1',
               assetName: 'Name 2',
               assetType: 'Type 2'
           },
           {
               family: 'Family 1',
               assetName: 'Name 3',
               assetType: 'Type 3'
           },
           {
               family: 'Family 2',
               assetName: 'Name 4',
               assetType: 'Type 4'
           },
           {
               family: 'Family 2',
               assetName: 'Name 5',
               assetType: 'Type 5'
           },
           {
               family: 'Family 3',
               assetName: 'Name 6',
               assetType: 'Type 6'
           }
       ];
       
       // building a map here basis family
       let groupedDataMap = new Map();
       samples.forEach(product => {
           if (groupedDataMap.has(product.family)) {
               groupedDataMap.get(product.family).products.push(product);
           } else {
               let newProduct = {};
               newProduct.family = product.family;
               newProduct.products = [product];
               groupedDataMap.set(product.family, newProduct);
           }
       });

       // building a products list wrapper of eg { rowspan : N, products: [], family: 'sample family'}
       let itr = groupedDataMap.values();
       let productArray = [];
       let result = itr.next();
       while (!result.done) {
           result.value.rowspan = result.value.products.length + 1;
           productArray.push(result.value);
           result = itr.next();
       }
       return productArray;
   }

Here is the code for HTML.

<tbody>
    <template if:true={productArray}>
        <template for:each={productArray} for:item="family">
            <tr key={family.family} class="slds-hint-parent">
                <td data-label="family" rowspan={family.rowspan}>
                    {family.family}
                </td>
            </tr>
            <template for:each={family.products} for:item="product">
                <tr key={product.assetName}>
                    <td key={product.assetName} data-label="family">
                        {product.assetName}
                    </td>
                    <td key={product.assetName} data-label="family">
                        {product.assetType}
                    </td>
                </tr>
            </template>
        </template>
    </template>
</tbody>

Here is the output:

enter image description here

1

instead of rowspan and colspan, that is not supported by lightning:datatable https://developer.salesforce.com/docs/component-library/bundle/lightning:datatable

You can use "cellAttributes" & css to perform border cell border appearance

var tableColumn = { 
            "label": sampleRow.fieldLabels[fieldName],
            "fieldName": fieldName,
            "type": sampleRow.fieldTypes[fieldName],
            "sortable": true,
            "cellAttributes" : {"class":{"fieldName": fieldName + "-css" }}
};

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.