Building Enterprise Application with Sharepoint Framework(SPFx), React, and PNP TreeView
- Sumit Dey
- Mar 9, 2022
- 3 min read
In this article, we would discuss building enterprise applications with Sharepoint Framework(SPFx), React web part using the PNP Treeview component. PNP TreeView would allow the graphical presentation of hierarchical data. It would expand to the number of sub-items and details about subitems. In this article, we would try to build an application with a four-level of hierarchy(TreeView), after selecting any district(s)/House user able to confirm the selection, then we can able to show the document library according to the particular district/house using accordion.

Create Document Libraries
Create document libraries called House 1 and House 2 on the Sharepoint site and upload a few test documents.
Let's start the process, First, we need to create SharePoint client-side web part, please follow this document for more details.
Create a new web part using the following command
yo @microsoft/sharepoint
Install the dependency library that requires for TreeView control.
npm install @pnp/sp --save
npm install @pnp/spfx-controls-react --save
Preparation of data
First, we need to prepare data for the hierarchy(TreeView), we need to build the following JSON format of data for this tree control.
private testdata:any = [
{
key:"RegionID-1",
label:"RegionID -1",
subLabel: "This is a sub label for node",
children:[
{
key: "TestZone-2",
label: "ZoneID - 2",
children: [
{
key:"District-3",
label:"DistrictID -3",
children: [
{
key:"1",
label:"House 1"
},
{
key:"2",
label:"House 2"
},
{
key:"3",
label:"House 3"
},
{
key:"4",
label:"House 4"
}
]
}
]
}
]
}
The key would be unique for the whole structure.
Let's start with the render() function
<div className={styles.treeview}>
<div className={ styles.container }>
<div className={ styles.row }>
<div>
/* Specify the input search text box*/
<input className={styles.filtertext} placeholder="Filter a specific house/district" onKeyUp={(e:any) => this.filterValue(e)}*/
/* Now we have to define the TeeView */
<div><Spinner>Loading items ...</Spinner></div> :
(
<TreeView
items={this.testdata}
defaultExpanded={false}
selectionMode={TreeViewSelectionMode.Multiple}
selectChildrenIfParentSelected={true}
selectChildrenMode = {SelectChildrenMode.Select | SelectChildrenMode.Unselect }
showCheckboxes={true}
treeItemActionsDisplayMode={TreeItemActionsDisplayMode.ContextualMenu}
defaultSelectedKeys={this.state.selectItems}
expandToSelected={true}
defaultExpandedChildren={false}
onExpandCollapse={this.onExpandCollapseTree}
onSelect={this.onItemSelected}
onRenderItem={this.renderCustomTreeItem}
/>
)
/* Confirm selection button */
<button className={`${styles.goButton}} disabled={this.state.selectItems.length===0} onClick={() => this.goButton()}>Confirm Selection</button>
</div>
<div>
/* Here we have to show the Accordion of document libraries */
/* find out the house number from the hierarchy data */
return <Accordion title={value} defaultCollapsed={this.state.defaultCollapsed} className={"itemCell itembackground"} >
<Iframe data={'https://<domain>.sharepoint.com/sites/<sitename>/Shared Documents/'+housenumber}/>
</Accordion>
</div>
</div>
</div>
</div>
Now defined the state variables
public state = {
selectItems:[],
searchItems:[],
loading: true,
cancelSelection: true,
filter:null,
timeout:0,
sortType:'a',
loadAccordion: true,
defaultCollapsed: true,
};
After selection of the component how to load the accordion after pressing the "Confirm selection button".
goButton=()=>{
let sb = '';//sb = [];
for(let i=0;i<this.state.selectItems.length;i++) {
sb=sb+this.state.selectItems[i]+',';
}
window.location.reload(); // Reload the page
}
Here is the function for searching the District/House
filterValue=(e:any)=>{
let keyval = e.target.value;
this.setState({filter: keyval});
if (e.target.value == '' || e.target.value ==null || e.target.value == undefined) {
this.state.searchItems = [];
clearTimeout(this.state.timeout);
}
else {
if (this.state.timeout) {
clearTimeout(this.state.timeout);
}
if (e.keyCode === 8) {
this.state.searchItems = [];
e.target.value = '';
keyval = '';
} else {
new searchData().searchFilterData(this.testdata,keyval, this.state);
}
return null;
}
When the user selects a specific item from the tree(District/House)
onItemSelected=(items: ITreeItem[])=>{
let itemslocal=[];
for(let i=0;i<items.length;i++) {
itemslocal[i]=items[i].key;
this.setState({selectItems: itemslocal})
}
Sorting the data showing to the accordion that we can put into the constructor.
private sort(data,type?) {
if(!data.length) {
return data;
}
if (type != undefined && type.toLowerCase() === 'd') {
return data.sort((b,a) => {
let x = Number(a.substring(a.indexOf('-') + 1));let y = Number(b.substring(b.indexOf('-') + 1));
return ((x < y) ? -1 : ((x > y) ? 1:0));
});
} else {
return data.sort((a,b) => {
let x = Number(a.substring(a.indexOf('-') + 1));let y = Number(b.substring(b.indexOf('-') + 1));
return ((x < y) ? -1 : ((x > y) ? 1:0));
});
}
}
Deploy the Application
Please find the following command to build and package the solution
gulp clean & gulp bundle --ship & gulp package-solution --ship
Browser the SPO app catalog of your tenant and deploy the application, it is the .sppkg file and it is found in sharepoint/solution folder, after deploying the package you can find this application in the Sharepoint pages across the tenant.
Comments