Sunday, October 3, 2021

File upload with metadata by using SPFx React framework with bootstrap

 File upload with metadata by using SPFx React framework with bootstrap:


List Structure



Library:


F:\SPFx\DemoReactWP

Install required

yo @microsoft/sharepoint

npm install jquery --save

npm install jqueryui --save

npm install @types/jquery --save-dev

npm install @types/jqueryui --save-dev

 

Bootstrap:

npm i react-bootstrap --save

npm install bootstrap@4 --save

npm install @types/bootstrap@4 --save-dev

 npm install url-loader --save-dev

 

SP install:

npm install @pnp/common @pnp/sp@2.11.0 @pnp/logging @pnp/odata --save

 

Go to -> webpart.ts file

Latest Version: Nodejs 16.13.0

protected onInit(): Promise<void> {

    sp.setup({

      spfxContext: this.context as any

    });

    return this._getEnvironmentMessage().then(message => {

      this._environmentMessage = message;

    });

  }

ü  Properties at webpart.ts:

 siteUrl: this.context.pageContext.web.absoluteUrl

 

 

Past version Nodejs 10.16.0

import {sp} from '@pnp/sp/presets/all'

 Add below code before the render method:

 protected async onInit(): Promise<void> {

    const _ = await super.onInit();

    sp.setup({

      spfxContext: this.context

    });

  }

     Add at props.ts file     

siteUrl:string;

call a method:

  componentDidMount(): void {

    this.getData();

  }

  public getData = async () => {   

      sp.web.lists.getByTitle("DocumentExpiry").items.getAll().then(items => {

        debugger; console.log(items);

      })

    }   

  }




 Add Style (.SCSS)

 

 .itemField {

    displayflex;

    padding5px;

.fieldLabel {

      min-width100px;

    }

  }

  

.buttonSection{

    padding-top20px;

    displayflex;

  }

.myTable{

  border1px solid #ddd;

}

.displayNone{

  displaynone;

}

.paddingTop10{

  padding-top10px

}

.tblThread{

  background#17a2b8colorwhite;

}

.tblTh{

  border1px solid #ddd;

}

 

Props.ts:

import { WebPartContext } from "@microsoft/sp-webpart-base";

export interface IMyWpProps {

  description: string;

  context:WebPartContext;  

}

  

Config.json

 "externals": {

  "jquery": {

    "path":"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js",

      "globalName""jquery"

    },

    "bootstrap": {     

     "path""node_modules\bootstrap/dist/js/bootstrap.min.js",

      "globalName""bootstrap",

      "globalDependencies": ["jquery"]

    } 

  },

  

Component file (.tsx)

import { SPComponentLoader } from '@microsoft/sp-loader';

import * as $ from 'jquery';

import 'jqueryui';

import 'bootstrap/dist/css/bootstrap.css';

import { sp } from "@pnp/sp/presets/all";

import "@pnp/sp/webs";

import "@pnp/sp/lists";

import "@pnp/sp/items";

 

Add a constructor class:

Nodejs 16.03.0

Add after  super(props);

    sp.setup({

      sp: {

        baseUrl: this.props.siteUrl

      },

    });

Copy the code below and past after ‘export default class MyWp extends React.Component<IMyWpProps, {}> {‘

constructor(props: IMyWpProps) {

    super(props);

    SPComponentLoader.loadCss("//code.jquery.com/ui/1.9.1/themes/smoothness/jquery-ui.css");

    SPComponentLoader.loadCss("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css");

  }

  public componentDidMount() {

    this.PageLoad();

  }

 

Render () method return

 <div className="container-fluid">

        <div className="row">

          <div className="col-sm">

            <label>

              <h3>Document Upload using SPFx -React</h3>

            </label>

          </div>

        </div>

        <div className="row">

          <div className="col-sm">

            <label>File Upload:</label>

            <input id="fileuploader" type="file" className="form-control" />

          </div>

          <div className="col-sm">

          </div>

        </div>

        <div className="row">

          <div className="col-sm">

            <label>Project Code:</label>

            <select id="projectcode" className="form-control">

             <option>-- select project code --</option>

              <option>001</option>

              <option>002</option>

              <option>003</option>

              <option>004</option>

              <option>005</option>

            </select>

          </div>

          <div className="col-sm">

            <label>Project Title:</label>

            <input type="text" id="projecttitle" className="form-control" />

          </div>

          <div className="col-sm">

            <label>Document Type:</label>

            <select id="documenttype" className="form-control">

            <option>-- select document --</option>

              <option>Type1</option>

              <option>Type2</option>

              <option>Type3</option>

              <option>Type4</option>

              <option>Type5</option>

            </select>

          </div>

 

        </div>

        <div className="row">

          <div className="col-sm">

            <label>Requestor:</label>

            <select id="originator" className="form-control">

            <option>-- select requestor --</option>

              <option>Sample1</option>

              <option>Sample2</option>

              <option>Sample3</option>

              <option>Sample4</option>

              <option>Sample5</option>

            </select>

          </div>

          <div className="col-sm">

            <label>Valid From:</label>

            <input type="text" id="validfrom" className="form-control" />

          </div>

          <div className="col-sm">

            <label>Valid Till:</label>

            <input type="text" id="validto" className="form-control" />

          </div>

        </div>

 

        <div className="row">

 

          <div className="col-sm">

            <label>Currency:</label>

            <select id="currency" className="form-control">

            <option>-- select currency --</option>

              <option>AED</option>

              <option>SAD</option>

              <option>INR</option>

              <option>USD</option>

              <option>QAR</option>

            </select>

          </div>

 

          <div className="col-sm">

            <label>Amount:</label>

            <input type="text" id="amount" className="form-control" />

          </div>

 

        </div>

 

        <div className="row">

          <br />

        </div>

 

        <div className="row">

          <div className="col-sm">

            <input type="button" id="btnsave" value="Save" className="btn-danger form-control" /></div>

          <div className="col-sm">

            <input type="button" id="btncancel" value="Cancel" className="btn-info form-control" /></div>

          <div className="col-sm"></div>

        </div>

        <div className="row">

          <br />

        </div>

        <div className="row" >

          <div className="col-sm">

            <label id="itemId" />

            <table className={styles.myTable}>

              <thead className={styles.tblThread}>

                <tr>

                  <th className={styles.tblTh}>Project Code</th>

                  <th className={styles.tblTh}>Project Title</th>

                  <th className={styles.tblTh}>Document Type</th>

                  <th className={styles.tblTh}>Requestor</th>

                  <th className={styles.tblTh}>Amount</th>

                  <th className={styles.tblTh}>Actions</th>

                </tr>

              </thead>

              <tbody id="expirydocuments"></tbody>

            </table>

          </div>

        </div>

      </div>

 

Component (.tsx) file full code:

import * as React from 'react';

import styles from './MyWp.module.scss';

import { IMyWpProps } from './IMyWpProps';

import { escape } from '@microsoft/sp-lodash-subset';

 

import { SPComponentLoader } from '@microsoft/sp-loader';

import * as $ from 'jquery';

import 'jqueryui';

import 'bootstrap/dist/css/bootstrap.css';

import { sp } from "@pnp/sp/presets/all";

import "@pnp/sp/webs";

import "@pnp/sp/lists";

import "@pnp/sp/items";

 

export default class MyWp extends React.Component<IMyWpProps, {}> {

  constructor(props: IMyWpProps) {

    super(props);

    SPComponentLoader.loadCss("//code.jquery.com/ui/1.9.1/themes/smoothness/jquery-ui.css");

    SPComponentLoader.loadCss("https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css");

  }

  public componentDidMount() {

    this.PageLoad();

  }

  public render(): React.ReactElement<IMyWpProps> {

 

    return (

      <div className="container-fluid">

        <div className="row">

          <div className="col-sm">

            <label>

              <h3>Document Upload using SPFx -React</h3>

            </label>

          </div>

        </div>

        <div className="row">

          <div className="col-sm">

            <label>File Upload:</label>

            <input id="fileuploader" type="file" className="form-control" />

          </div>

          <div className="col-sm">

          </div>

        </div>

        <div className="row">

          <div className="col-sm">

            <label>Project Code:</label>

            <select id="projectcode" className="form-control">

             <option>-- select project code --</option>

              <option>001</option>

              <option>002</option>

              <option>003</option>

              <option>004</option>

              <option>005</option>

            </select>

          </div>

          <div className="col-sm">

            <label>Project Title:</label>

            <input type="text" id="projecttitle" className="form-control" />

          </div>

          <div className="col-sm">

            <label>Document Type:</label>

            <select id="documenttype" className="form-control">

            <option>-- select document --</option>

              <option>Type1</option>

              <option>Type2</option>

              <option>Type3</option>

              <option>Type4</option>

              <option>Type5</option>

            </select>

          </div>

 

        </div>

        <div className="row">

          <div className="col-sm">

            <label>Requestor:</label>

            <select id="originator" className="form-control">

            <option>-- select requestor --</option>

              <option>Sample1</option>

              <option>Sample2</option>

              <option>Sample3</option>

              <option>Sample4</option>

              <option>Sample5</option>

            </select>

          </div>

          <div className="col-sm">

            <label>Valid From:</label>

            <input type="text" id="validfrom" className="form-control" />

          </div>

          <div className="col-sm">

            <label>Valid Till:</label>

            <input type="text" id="validto" className="form-control" />

          </div>

        </div>

 

        <div className="row">

 

          <div className="col-sm">

            <label>Currency:</label>

            <select id="currency" className="form-control">

            <option>-- select currency --</option>

              <option>AED</option>

              <option>SAD</option>

              <option>INR</option>

              <option>USD</option>

              <option>QAR</option>

            </select>

          </div>

 

          <div className="col-sm">

            <label>Amount:</label>

            <input type="text" id="amount" className="form-control" />

          </div>

 

        </div>

 

        <div className="row">

          <br />

        </div> 

        <div className="row">

          <div className="col-sm">

            <input type="button" id="btnsave" value="Save" className="btn-danger form-control" /></div>

          <div className="col-sm">

            <input type="button" id="btncancel" value="Cancel" className="btn-info form-control" /></div>

          <div className="col-sm"></div>

        </div>

        <div className="row">

          <br />

        </div>

        <div className="row" >

          <div className="col-sm">

            <label id="itemId" />

            <table className={styles.myTable}>

              <thead className={styles.tblThread}>

                <tr>

                  <th className={styles.tblTh}>Project Code</th>

                  <th className={styles.tblTh}>Project Title</th>

                  <th className={styles.tblTh}>Document Type</th>

                  <th className={styles.tblTh}>Requestor</th>

                  <th className={styles.tblTh}>Amount</th>

                  <th className={styles.tblTh}>Actions</th>

                </tr>

              </thead>

              <tbody id="expirydocuments"></tbody>

            </table>

          </div>

        </div>

      </div>

    );

  }

 

  public PageLoad(): Promise<string> {

    try {      

      return new Promise<string>(async (resolve, reject) => {

        $("#validfrom").datepicker();

        $("#validto").datepicker();

        $("#btnsave").click(f => {

          let itemId = $("#itemId").val();

          if (itemId == "" || itemId == null) {

            this.AddUpdate("Add""");

          }

          else { this.AddUpdate("Update", itemId); }

        });

        $("#btncancel").click(f => {

          $("#itemId").val("");

          this.ClearControl();

        });

        this.BindData();

        resolve('Loaded succesfully');

      })

    }

    catch (ex) {

      alert(ex.message);

    }

  }

 

  public BindData = async () => {

    console.log('Rk BinddataLoad');

    sp.web.lists.getByTitle("DocumentExpiry").items.getAll().then(items => {

      $("#expirydocuments").html("");

      items.forEach(item => {        

        let htmlContent = `

           <tr> 

           <td style="border: 1px solid #ddd;">${item.ProjectCode}</td> 

           <td style="border: 1px solid #ddd;">${item.ProjectTitle == null ? '' : item.ProjectTitle}</td>

           <td style="border: 1px solid #ddd;">${item.DocumentType}</td> 

           <td style="border: 1px solid #ddd;">${item.Originator}</td>            

           <td style="border: 1px solid #ddd;">${item.Amount == null ? '' : item.Amount} ${item.Currency}</td> 

           

           <td style="border: 1px solid #ddd;">

             <input id="edit_${item.Id}" class="edit" type="button" value="Edit">

             <input type="button" id="btndelete_${item.Id}" class="btndelete" value="Delete" > </td>'; 

             </tr>`;

        $("#expirydocuments").append(htmlContent);

      });

      this.EventBinding();

    });

  }

 

  public EventBinding = async () => {

    try {

      $(".btndelete").click(w => {

        let itemId = Number(w.delegateTarget.id.split("_")[1]);

        if (confirm("Are you sure,you want to delete this item?")) {

          this.DeleteItem(itemId);

        }

      });

 

      $(".edit").click(w => {

        let itemId = Number(w.delegateTarget.id.split("_")[1]);

        this.LoadItemDetails(itemId);

      });

    }

    catch (ex) {

      alert(ex.message);

    }

  }

 

  public LoadItemDetails = async (itemid: number) => {

    sp.web.lists.getByTitle("DocumentExpiry").items.getById(itemid).get().then(item => {

      $("#itemId").val(item.Id);

      $("#projectcode").val(item.ProjectCode);

      $("#projecttitle").val(item.ProjectTitle = null ? '' : item.ProjectTitle);

      $("#documenttype").val(item.DocumentType);

      $("#originator").val(item.Originator);

      debugger;

      $("#validfrom").val(item.ValidFrom = null ? '' :

        $.datepicker.formatDate('mm/dd/yy'new Date(item.ValidFrom)));

      $("#validto").val(item.ValidTill = null ? '' :

        $.datepicker.formatDate('mm/dd/yy'new Date(item.ValidTill)));

      $("#currency").val(item.Currency);

      $("#amount").val(item.Amount = null ? '' : item.Amount);

 

    });

  }

 

  public DeleteItem = async (itemid: number) => {

    const webpart: MyWp = this;

    sp.web.lists.getByTitle("DocumentExpiry").items.getById(itemid).delete().then(res => {

      alert("Item Deleted.");

      webpart.BindData();

    }).catch(error => { console.log(error); });

  }

  private AddUpdate(commandType: string, itemid: any): void {   

    debugger;

    let projectCode = $("#projectcode").val();

    let projectTitle = $("#projecttitle").val();    

    let documentType = $("#documenttype").val();

    let originator = $("#originator").val();

    let vF: any = $("#validfrom").val();

    let vT: any = $("#validto").val();

    let validFrom = new Date(vF)

    let validTill = new Date(vT);

    let currency = $("#currency").val();

    let amount = $("#amount").val();

 

    if (commandType == "Add") {

      // to find file uploader control by element id 

      //let input = <HTMLInputElement>document.getElementById("fileuploader");

      //let file = input.files[0];

      try{

      let file = (document.querySelector("#fileuploader"as HTMLInputElement).files[0]; 

      

      //upload small file in document library  

      console.log('RK Url' + this.props.context.pageContext.site.serverRelativeUrl);   

      sp.web.getFolderByServerRelativeUrl(this.props.context.pageContext.site.serverRelativeUrl+"/DocumentExpiry").files

      .add( file.name,file,true).then(f=> { 

      // use below to update the properties of document 

      f.file.getItem().then(item =>

        item.update({ 

          ProjectCode:projectCode, 

          ProjectTitle:projectTitle, 

          DocumentType:documentType, 

          Originator:originator, 

          ValidFrom:validFrom, 

          ValidTill:validTill, 

          Currency:currency, 

          Amount:amount 

          }).then(f=>{

             alert("File uploaded successfully"); $("#itemId").val(""); 

             this.BindData(); 

             this.ClearControl();

             }).catch(error=>{ console.log(error); 

            });

           }); 

          });

        }

        catch(ex){

          alert(ex.message);

        }

      //

    }

    else {

      sp.web.lists.getByTitle("DocumentExpiry").items.getById(itemid).update({

        ProjectCode: projectCode,

        ProjectTitle: projectTitle,

        DocumentType: documentType,

        Originator: originator,

        ValidFrom: validFrom,

        ValidTill: validTill,

        Currency: currency,

        Amount: amount

      }).then(item => {

        alert("Item Updated successfully");

        $("#itemId").val("");

        this.BindData();

        this.ClearControl();

      }).catch(error => { console.log(error); });

    }

  }

 

  public ClearControl = async () => {

    $("#projecttitle").val('');

    $("#validfrom").val('');

    $("#validto").val('');

    $("#amount").val('');

    $('#projectcode').val("-- select project code --");

    $('#documenttype').val("-- select document --");

    $('#originator').val("-- select requestor --");

    $('#currency').val("-- select currency --"); 

  } 

}

  

Webpart.ts – Full file code

import * as React from 'react';

import * as ReactDom from 'react-dom';

import { Version } from '@microsoft/sp-core-library';

import {

  IPropertyPaneConfiguration,

  PropertyPaneTextField

from '@microsoft/sp-property-pane';

import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';

 import * as strings from 'MyWpWebPartStrings';

import MyWp from './components/MyWp';

import { IMyWpProps } from './components/IMyWpProps';

import {sp} from '@pnp/sp/presets/all'

 

export interface IMyWpWebPartProps {

  description: string;

}

 

export default class MyWpWebPart extends BaseClientSideWebPart<IMyWpWebPartProps> {

  protected async onInit(): Promise<void> {

    const _ = await super.onInit();

    sp.setup({

      spfxContext: this.context

    });

  }

 

  public render(): void {

    const element: React.ReactElement<IMyWpProps> = React.createElement(

      MyWp,

      {

        description: this.properties.description,

        context:this.context

      }

    ); 

    ReactDom.render(element, this.domElement);

  }

 

  protected onDispose(): void {

    ReactDom.unmountComponentAtNode(this.domElement);

  }

 

  protected get dataVersion(): Version {

    return Version.parse('1.0');

  }

 

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {

    return {

      pages: [

        {

          header: {

            description: strings.PropertyPaneDescription

          },

          groups: [

            {

              groupName: strings.BasicGroupName,

              groupFields: [

                PropertyPaneTextField('description', {

                  label: strings.DescriptionFieldLabel

                })

              ]

            }

          ]

        }

      ]

    };

  }

}

  

 

Config.json - Full file code

{

  "$schema""https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",

  "version""2.0",

  "bundles": {

    "my-wp-web-part": {

      "components": [

        {

          "entrypoint""./lib/webparts/myWp/MyWpWebPart.js",

          "manifest""./src/webparts/myWp/MyWpWebPart.manifest.json"

        }

      ]

    }

  },

  "externals": {

    "jquery": {

      "path""https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js",

      "globalName""jquery"

    },

    "bootstrap": {     

     "path""node_modules\bootstrap/dist/js/bootstrap.min.js",

      "globalName""bootstrap",

      "globalDependencies": ["jquery"]

    } 

  },

  "localizedResources": {

    "MyWpWebPartStrings""lib/webparts/myWp/loc/{locale}.js"

  }

}

 

 


No comments:

Post a Comment