Skip to main content
4 of 4
added 9 characters in body
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/2/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:10px;"
                },
                {
                    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.

EDIT:

As per ytiq's comment I added the logic on how to flatten the data given in the question. here is the updated playground

Note that the logic to flatten the original data structure may need to be changed based on factors like:

  1. how many levels deep the original data structure is going to be
  2. Is Id going to be unique across entire hierarchy.
javanoob
  • 9k
  • 15
  • 77
  • 143