top of page

Building Enterprise Application with Sharepoint Framework(SPFx), React, and PNP TreeView

  • Writer: Sumit Dey
    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


© 2023 by T-MARKET. Proudly created with Wix.com

  • Facebook - Black Circle
  • Twitter - Black Circle
  • Google+ - Black Circle
bottom of page