Skip to main content
1 of 4
javanoob
  • 9k
  • 15
  • 77
  • 143

I think there are are two ways to achieve what you want:

  1. Don't change underlying data structure but change UI markup handle data structure.
  2. Change underlying data structure but keep UI markup simple.

I chose option 2 and was able to get this output:

Link to playground: https://developer.salesforce.com/docs/component-library/tools/playground/KG-dO5AL/1/edit

enter image description here

app.html:

<template>
  <table>
    <thead>
        <th>Name</th>
    </thead>
    <tbody>
        <template for:each={tableData} for:item="rowData">
            <tr key={rowData.Id} class={rowData.rowStyle}>
                <td>
                    <span style={rowData.nameStyle}>
                        <lightning-icon icon-name={rowData.iconName} 
                        size=x-small 
                        onclick={showOrHideChildrenRows} 
                        data-rowid={rowData.Id}
                        data-expanded="false">
                        </lightning-icon>
                        {rowData.Name}
                    </span>
                </td>
            </tr>
        </template>
    </tbody>
  </table>
</template>

app.js:

import { LightningElement, track } from "lwc";

export default class App extends LightningElement {
    @track
    tableData =[
                {
                    Name: "United States",
                    Id: 1,
                    iconName: "utility:chevronright",
                    parentId : null,
                    rowStyle : "",
                    nameStyle : ""
                },
                {
                    Name: "Massachusetts",
                    Id: 2,
                    iconName: "utility:chevronright",
                    parentId: 1,
                    rowStyle : "hide",
                    nameStyle : "margin-left:10px;"
                },
                {
                    Name: "Boston",
                    Id: 3,
                    iconName: "",
                    parentId: 2,
                    rowStyle : "hide",
                    nameStyle : "margin-left:20px;"
                },              
                {
                    Name: "New York",
                    Id: 4,
                    iconName: "",
                    parentId : 1,
                    rowStyle : "hide",
                    nameStyle : "margin-left:20px;"
                },
                {
                    Name: "Vatican City",
                    Id : 5,
                    iconName: "",
                    parentId : null,
                    rowStyle : "",
                    nameStyle : ""
                },
                {
                    Name: "Canada",
                    Id : 6,
                    iconName: "utility:chevronright",
                    parentId : null,
                    rowStyle : "",
                    nameStyle : ""
                },
                {
                    Name: "Ontario",
                    Id : 7,
                    iconName: "",
                    parentId : 6,
                    rowStyle : "hide",
                    nameStyle : "margin-left:10px;"
                },
                {
                    Name: "Alberta",
                    Id : 8,
                    iconName: "",
                    parentId : 6,
                    rowStyle : "hide",
                    nameStyle : "margin-left:10px;"
                }
            ];

    showOrHideChildrenRows(event){
        let rowId = event.target.dataset.rowid;
        let isExpanded = event.target.dataset.expanded;
        event.target.iconName = JSON.parse(isExpanded) ? "utility:chevronright": "utility:chevrondown";
        event.target.dataset.expanded = JSON.stringify(!JSON.parse(isExpanded));
         
        this.tableData = this.tableData.map((obj) => {
            if(obj.parentId == rowId &&  !JSON.parse(isExpanded)){
                obj.rowStyle = "";
            }
            if(obj.parentId == rowId && JSON.parse(isExpanded)){
                obj.rowStyle = "hide";
            }
            return obj;
        });
        console.log(this.tableData);

    }

}

Each element in the data structure has these special attributes:

  • parentId - to relate each element to its parent element.
  • rowStyle - to hide or show children elements.
  • nameStyle - to apply proper indentation to parent elements.
javanoob
  • 9k
  • 15
  • 77
  • 143