LWC-Custom Tree with indented checkbox with event (3th-Level Hierarchy)
Sample picture of the custom lightning web component tree with the indented checkbox.
Sample JSON
[
{
"Items": [
{
"Items": [
{
"name": "Dash Absolute Return Bond Fund",
"recId": "000007654"
},
{
"name": "Dash Investment Management LLC",
"recId": "00004445"
},
{
"name": "Dash Institutional Trust Company",
"recId": "000077788"
},
{
"name": "Dash Institutional Trust Company",
"recId": "000088995"
},
{
"name": "Dash Institutional Trust Company",
"recId": "00001212"
},
{
"name": "Dash Financial Management Inc",
"recId": "01010101"
},
{
"name": "Dash Investment Management LLC",
"recId": "22223333"
},
{
"name": "Dash Advisors (UK) Limited",
"recId": "45645612"
}
],
"name": "DASH INVESTMENT MANAGEMENT",
"recId": "000000123"
}
],
"name": "DASH GROUP",
"recId": "00001234"
}
]
CustomTree.html
Make an LWC component that can be used as a reusable component.
<template>
<div class="slds-text-longform" id="dashTree">
<ul class="myUL">
<!--=================LEVEL-1 ITERATION==========================-->
<template for:each={records} for:item="record" for:index="parentRec">
<li key={record.recId}>
<!--=================LEVEL-2 ITERATION==========================-->
<template if:true={record.Items}>
<span class="caret">
<template if:true={showCheckBox}>
<input type="checkbox" value={record.recId} onclick={collectItem} class="chkTree_1">
</template>
<span class="onHover">{record.name}</span>
</span>
<ul class="nested">
<template for:each={record.Items} for:item="childRec_1" for:index="childRec_idx1">
<li key={childRec_1.recId}>
<!--=================LEVEL-3 ITERATION==========================-->
<template if:true={childRec_1.Items}>
<span class="caret">
<template if:true={showCheckBox}>
<input type="checkbox" value={childRec_1.recId} onclick={collectItem} class="chkTree_1">
</template>
<span class="onHover">{childRec_1.name}</span>
</span>
<ul class="nested">
<template for:each={childRec_1.Items} for:item="childRec_2" for:index="childRec_idx2">
<li key={childRec_2.recId}>
<template if:true={showCheckBox}>
<input type="checkbox" value={childRec_2.recId} onclick={collectItem} class="chkTree_1">
</template>
<span class="onHover">{childRec_2.name}</span>
</li>
</template>
</ul>
</template>
<template if:false={childRec_1.Items}>
<template if:true={showCheckBox}>
<input type="checkbox" value={childRec_1.recId} onclick={collectItem} class="chkTree_1">
</template>
<span class="onHover">{childRec_1.name}</span>
</template>
</li>
</template>
</ul>
</template>
<template if:false={record.Items}>
<template if:true={showCheckBox}>
<input type="checkbox" value={record.recId} onclick={collectItem} class="chkTree_1">
</template>
<span class="onHover">{record.name}</span>
</template>
</li>
</template>
</ul>
</div>
</template>
CustomTree.js
import { LightningElement, api, track } from 'lwc';
export default class CustomTree extends LightningElement {
@api searchValue = '';
@api showCheckBox = false;
@api records;
@track error;
renderedCallback() {
//alert("Welcome to LWC Constructor!");
let toggler = this.getElementsByClassName("caret");
//alert(toggler.length)
var i;
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function () {
this.parentElement.querySelector(".nested").classList.toggle("active");
this.classList.toggle("caret-down");
});
}
}
collectItem(event) {
try {
//alert(event.target.value + ', ' + event.target.checked);
var tempList = [];
let toggler = this.template.querySelectorAll(".chkTree_1");
var i;
for (i = 0; i < toggler.length; i++) {
//alert(toggler[i].value + ', ' + toggler[i].checked);
if (toggler[i].checked) {
tempList.push(toggler[i].value);
}
}
//alert("Child: " + tempList);
//Passing selected item to parent
const custEvent = new CustomEvent(
'select', {
detail: { 'selectedItems': tempList }
});
this.dispatchEvent(custEvent);
}
catch (exception) {
alert(exception);
}
}
parseResponse(result) {
//alert(JSON.stringify(result));
let parseData = JSON.parse(JSON.stringify(result));
//alert(JSON.stringify(parseData['Items']));
for (let i = 0; i < parseData.length; i++) {
if (parseData['Items'] != undefined) {
parseData[i]._children = parseData['Items'];
//ITERATION CODE FOR LEVEL-2
for (let j = 0; j < parseData[i]._children.length; j++) {
if (parseData[i]._children[j]['Items'] != undefined) {
parseData[i]._children[j]._children = parseData[i]._children[j]['Items'];
//ITERATION CODE FOR LEVEL-3
for (let k = 0; k < parseData[i]._children[j]._children.length; k++) {
if (parseData[i]._children[j]._children[k]['Items'] != undefined) {
parseData[i]._children[j]._children[k]._children = parseData[i]._children[j]._children[k]['Items'];
}
delete parseData[i]._children[j]._children[k]['Items'];
}
}
delete parseData[i]._children[j]['Items'];
}
}
}
delete parseData['Items'];
this.records = parseData;
alert(JSON.stringify(parseData));
return this.records;
}
}
CustomTree.css
li, ul, .myUL {
list-style-type: none;
margin-left: 0;
padding-left: 17px;
line-height:25px;
}
.myUL {
margin: 0;
padding: 0;
}
.onHover:hover{
background-color:lightskyblue;
}
.caret {
cursor: pointer;
-webkit-user-select: none; /* Safari 3.1+ */
-moz-user-select: none; /* Firefox 2+ */
-ms-user-select: none; /* IE 10+ */
user-select: none;
}
.caret::before {
content: "\25B6";
color: black;
display: inline-block;
margin-right: 6px;
}
.caret-down::before {
-ms-transform: rotate(90deg); /* IE 9 */
-webkit-transform: rotate(90deg); /* Safari */
transform: rotate(90deg);
}
.nested {
display: none;
}
.active {
display: block;
}
How to reuse custom component
use the below code in your parent component as child.
<c-custom-tree records={bankingRecords}
show-check-box={showCheckBox_PH}
onselect={collectItem}>
</c-custom-tree>
pass parameter as above mentioned.
records= Sample JSON
show-check-box = true/false
onselect = Used JS Method to get selected items value.
Script to handle the event of on select of checkbox
collectItem(event) {
var selectedItems = event.detail.selectedItems;
if (selectedItems.length > 0)
alert("Selected Items: " + selectedItems);
}
Comments
Post a Comment