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 {
    display: flex;
    padding: 5px;
.fieldLabel {
      min-width: 100px;
    }
  }
  
.buttonSection{
    padding-top: 20px;
    display: flex;
  }
.myTable{
  border: 1px solid #ddd;
}
.displayNone{
  display: none;
}
.paddingTop10{
  padding-top: 10px
}
.tblThread{
  background: #17a2b8; color: white;
}
.tblTh{
  border: 1px 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