Forcetrails: How to create slds table with cell merge in lwc

Hello Trailblazers!!

I found this wonderful question on stack exchange, where the poster wanted to know how to create a lightning datatable with an option to merge duplicate cells. Then I started searching for this and found that as of now(Nov 19), there is no option to achieve this using the standard lightning-datatable component. So I ended up writing below sample code for this problem using SLDS table and Lightning Web Component.

So the solution was to group records by duplicate cells and use HTML rowspan to merge the rows.

Input data

Expected Output


So here is the code for my web component:
HTML
<template>
 <table class="slds-table slds-table_cell-buffer slds-table_bordered ">
  <thead>
   <tr class="slds-line-height_reset">
    <th class="" scope="col">
     <div class="slds-truncate" title="">Product Family</div>
    </th>
    <th class="" scope="col">
     <div class="slds-truncate" title="">Asset Name</div>
    </th>
    <th class="" scope="col">
     <div class="slds-truncate" title="">Asset Type</div>
    </th>
   </tr>
  </thead>
  <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>
 </table>
</template>

JS
import { LightningElement, track, api } from 'lwc';

export default class App extends LightningElement {
    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'
            }
        ];

        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);
            }
        });

        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;
    }
}

Output:



5 comments:
  1. Please provide some justification as I am a newbie

    ReplyDelete
    Replies
    1. Hi Dear Unknown, I have used rowspan property of the td HTML element here, by default this value is 1, but if you specify more than that browser merges two cells and this td element occupies spaces of two table cells. In JS code I grouped the rows with duplicate family names and based on the size of list I set the rowspan in the html.

      Delete
  2. Hi,

    Thanks for the wonderful post!

    I'm trying to implement similar functionality where I need to merge cells of different columns. Like in above example where duplicates are merged for 'Product Family', now I want to merge duplicates for 'Product Family' and 'Asset Name'.

    In my actual scenario, I need to merge cells of first 4 columns and last 2 columns have all values. I tried different scenarios but failed to get it working.

    Please share any ideas on this implementation.

    ReplyDelete
  3. Hi,

    Thanks for the wonderful post!

    I’m trying a similar implementation where I need to merge duplicates of more than 1 column. Like in above example I want to merge the cells of first 2 columns ‘Product Family and ‘Asset name’

    In my scenario, I need to merge cells of first 4 columns and last 2 columns will display all data in each row without merging cells.

    Please let me know how this can be accomplished.

    ReplyDelete
    Replies
    1. Hi Sneha, you need to use the lightning tree grid for that. Here is an example of that.
      https://salesforce.stackexchange.com/questions/289272/lwc-custom-tree-grid-issue

      I hope that helps, if you like the content please follow this blog.
      Let me know if any concerns.

      Delete

Hi there, comments on this site are moderated, you might need to wait until your comment is published. Spam and promotions will be deleted. Sorry for the inconvenience but we have moderated the comments for the safety of this website users. If you have any concern, or if you are not able to comment for some reason, reach email us at rahul@forcetrails.com