SPFx CRUD operations using React Framework code

props.ts: ICrudwithreactwebpart.ts

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

export interface ICrudWithReactWebPartProps {
  description: string;
  context:WebPartContext;
  siteUrl: string;
}
-------------
main.ts
CrudWithReactWebPart,
      {
        description: this.properties.description,
        context:this.context,
        siteUrl:this.context.pageContext.web.absoluteUrl
      }
----------------
State file: ICrudWithReactState.ts
import { ISoftwareListItem } from "./ISoftwareListItem";

export interface ICrudWithReactState{
    status: string;
    SoftwareListItems: ISoftwareListItem[];
    SoftwareListItem: ISoftwareListItem;
}
-----------
interface: ISoftwareListItem.ts
export interface ISoftwareListItem{
    Id:number;
    Title:string;
    SoftwareName: string;
    SoftwareVendor: string;
    SoftwareVersion: string;
    SoftwareDescription: string;
}
------------------------
Note: in tsx file, auto bind property onChange
npm i autobind-decorator
import autobind from 'autobind-decorator';

-------------
.tsx file

import * as React from 'react';
import styles from './CrudWithReactWebPart.module.scss';
import { ICrudWithReactWebPartProps } from './ICrudWithReactWebPartProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { ISoftwareListItem } from './ISoftwareListItem';
import { ICrudWithReactState } from './ICrudWithReactState';

import { ISPHttpClientOptions, SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';

import { TextField, PrimaryButton, DetailsList, DetailsListLayoutMode, CheckboxVisibility, SelectionMode, Dropdown, IDropdown, IDropdownOption, ITextFieldStyles, IDropdownStyles, DetailsRowCheck, Selection } from 'office-ui-fabric-react';
import autobind from 'autobind-decorator';


//configure columns for the details list component
let _softwareListColumns = [
  {
    key: 'ID',
    name: 'ID',
    fieldName: 'ID',
    minWidth: 50,
    maxWidth: 100,
    isResizable: true
  },
  {
    key: 'Title',
    name: 'Title',
    fieldName: 'Title',
    minWidth: 50,
    maxWidth: 100,
    isResizable: true
  },
  {
    key: 'SoftwareName',
    name: 'SoftwareName',
    fieldName: 'SoftwareName',
    minWidth: 50,
    maxWidth: 100,
    isResizable: true
  },
  {
    key: 'SoftwareVendor',
    name: 'SoftwareVendor',
    fieldName: 'SoftwareVendor',
    minWidth: 50,
    maxWidth: 100,
    isResizable: true
  },
  {
    key: 'SoftwareVersion',
    name: 'SoftwareVersion',
    fieldName: 'SoftwareVersion',
    minWidth: 50,
    maxWidth: 100,
    isResizable: true
  },
  {
    key: 'SoftwareDescription',
    name: 'SoftwareDescription',
    fieldName: 'SoftwareDescription',
    minWidth: 50,
    maxWidth: 100,
    isResizable: true
  }
];

const textFieldStyles: Partial<ITextFieldStyles> = { fieldGroup: { width: 300 } };
const narrowTextFields: Partial<ITextFieldStyles> = { fieldGroup: { width: 300 } };
const narrowDropdownStyles: Partial<IDropdownStyles> = { dropdown: { width: 300 } };

export default class CrudWithReactWebPart extends React.Component<ICrudWithReactWebPartProps, ICrudWithReactState> {


  private _selection: Selection;
  private _onItemsSelectionChanged = () =>{
    this.setState({
      SoftwareListItem:(this._selection.getSelection()[0] as ISoftwareListItem)
    });
  }

  constructor(props: ICrudWithReactWebPartProps, state: ICrudWithReactState) {
    super(props);
    this.state = {
      status: 'Ready',
      SoftwareListItems: [],
      SoftwareListItem: {
        Id: 0,
        Title: "",
        SoftwareName: "",
        SoftwareVendor: "Select an Option",
        SoftwareVersion: "",
        SoftwareDescription: ""
      }
    };

    this._selection = new Selection({
      onSelectionChanged:this._onItemsSelectionChanged,
    });
   
  }

  private _getListItems():Promise<ISoftwareListItem[]>{
    const url:string = this.props.siteUrl+"/_api/web/lists/getbytitle('SoftwareCatalog')/items";
    return this.props.context.spHttpClient.get(url,SPHttpClient.configurations.v1)
    .then(response =>{
      return response.json();
    })
    .then(json=>{
      return json.value;
    }) as Promise<ISoftwareListItem[]>;
  }

  public componentDidMount():void{
    this.bindDetailsList("All records have been loaded successfully");
  }
 
  @autobind
  public btnAdd_click():void{
    debugger;

    const url: string = this.props.siteUrl + "/_api/web/lists/getbytitle('SoftwareCatalog')/items";
   
    const SPHttpClientOptions:ISPHttpClientOptions = {
      "body":JSON.stringify(this.state.SoftwareListItem)
    };

    this.props.context.spHttpClient.post(url,SPHttpClient.configurations.v1,SPHttpClientOptions).then((response:SPHttpClientResponse) => {
      if(response.status === 201){
        alert("record has been added successfully");
        this.bindDetailsList("Record Added and All records loaded successfully!");
      }
      else{
        let errormessage: string = "An error occured. i.e "+response.status+" - "+response.statusText;
        this.setState({
          status:errormessage
        });
      }
    });
  }

  @autobind
  public btnUpdate_click():void{
    debugger;
    let id:number=this.state.SoftwareListItem.Id;

    const url: string = this.props.siteUrl + "/_api/web/lists/getbytitle('SoftwareCatalog')/items("+id+")";

    const headers:any={
      "X-HTTP-Method":"MERGE",
      "IF-MATCH":"*"
    };
   
    const SPHttpClientOptions:ISPHttpClientOptions = {
      "headers":headers,
      "body":JSON.stringify(this.state.SoftwareListItem)
    };

    this.props.context.spHttpClient.post(url,SPHttpClient.configurations.v1,SPHttpClientOptions).then((response:SPHttpClientResponse) => {
      if(response.status === 204){
        alert("record has been updated successfully");
        this.bindDetailsList("Record Updated and All loaded are updated successfully!");
      }
      else{
        let errormessage: string = "An error occured. i.e "+response.status+" - "+response.statusText;
        this.setState({
          status:errormessage
        });
      }
    });
  }

  @autobind
  public btnDelete_click():void{
    debugger;
    let id:number=this.state.SoftwareListItem.Id;

    const url: string = this.props.siteUrl + "/_api/web/lists/getbytitle('SoftwareCatalog')/items("+id+")";

    const headers:any={
      "X-HTTP-Method":"DELETE",
      "IF-MATCH":"*"
    };
   
    const SPHttpClientOptions:ISPHttpClientOptions = {
      "headers":headers
    };

    this.props.context.spHttpClient.post(url,SPHttpClient.configurations.v1,SPHttpClientOptions).then((response:SPHttpClientResponse) => {
      if(response.status === 204){
        alert("record has been deleted successfully");
        this.bindDetailsList("Record Deleted and All records loaded successfully!");
      }
      else{
        let errormessage: string = "An error occured. i.e "+response.status+" - "+response.statusText;
        this.setState({
          status:errormessage
        });
      }
    });
  }
  public bindDetailsList(message:string):void{
    this._getListItems().then(listItems=>{
      this.setState({
        SoftwareListItems:listItems,
        status:message
      });
    });
  }


  private onChangeIDField(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue: string): void {
    this.setState({
      SoftwareListItem:{
        Id:Number(newValue),
        Title:this.state.SoftwareListItem.Title,
        SoftwareName: this.state.SoftwareListItem.SoftwareName,
        SoftwareVendor: this.state.SoftwareListItem.SoftwareVendor,
        SoftwareVersion: this.state.SoftwareListItem.SoftwareVersion,
        SoftwareDescription:this.state.SoftwareListItem.SoftwareDescription
      }
    });
  }
  private onChangeTitleField(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue: string): void {
    this.setState({
      SoftwareListItem:{
        Id:this.state.SoftwareListItem.Id,
        Title:newValue,
        SoftwareName: this.state.SoftwareListItem.SoftwareName,
        SoftwareVendor: this.state.SoftwareListItem.SoftwareVendor,
        SoftwareVersion: this.state.SoftwareListItem.SoftwareVersion,
        SoftwareDescription:this.state.SoftwareListItem.SoftwareDescription
      }
    });
  }
  private onChangeSoftwareNameField(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue: string): void {
    this.setState({
      SoftwareListItem:{
        Id:this.state.SoftwareListItem.Id,
        Title:this.state.SoftwareListItem.Title,
        SoftwareName: newValue,
        SoftwareVendor: this.state.SoftwareListItem.SoftwareVendor,
        SoftwareVersion: this.state.SoftwareListItem.SoftwareVersion,
        SoftwareDescription:this.state.SoftwareListItem.SoftwareDescription
      }
    });
  }
  private onChangeDescriptionField(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue: string): void {
    this.setState({
      SoftwareListItem:{
        Id:this.state.SoftwareListItem.Id,
        Title:this.state.SoftwareListItem.Title,
        SoftwareName: this.state.SoftwareListItem.SoftwareName,
        SoftwareVendor: this.state.SoftwareListItem.SoftwareVendor,
        SoftwareVersion: this.state.SoftwareListItem.SoftwareVersion,
        SoftwareDescription:newValue
      }
    });
  }
  private onChangeSoftwareVersionField(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue: string): void {
    this.setState({
      SoftwareListItem:{
        Id:this.state.SoftwareListItem.Id,
        Title:this.state.SoftwareListItem.Title,
        SoftwareName: this.state.SoftwareListItem.SoftwareName,
        SoftwareVendor: this.state.SoftwareListItem.SoftwareVendor,
        SoftwareVersion: newValue,
        SoftwareDescription:this.state.SoftwareListItem.SoftwareDescription
      }
    });
  }
  private onChangeDropDownField(event: React.FormEvent<HTMLDivElement>, option?: IDropdownOption, index?: number): void {
    console.log(option.text);
    this.setState({
      SoftwareListItem:{
        Id:this.state.SoftwareListItem.Id,
        Title:this.state.SoftwareListItem.Title,
        SoftwareName: this.state.SoftwareListItem.SoftwareName,
        SoftwareVendor: option.text,
        SoftwareVersion: this.state.SoftwareListItem.SoftwareVersion,
        SoftwareDescription: this.state.SoftwareListItem.SoftwareDescription
      }
    });
  }

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

    const dropdownRef = React.createRef<IDropdown>();

    return (
      <div className={styles.crudWithReactWebPart}>
        <TextField
          label="ID"
          required={false}
          value={(this.state.SoftwareListItem.Id).toString()}
          styles={textFieldStyles}
          onChange={this.onChangeIDField.bind(this)}
        />
        <TextField
          label="Software Title"
          required={false}
          value={(this.state.SoftwareListItem.Title).toString()}
          styles={textFieldStyles}
          onChange={this.onChangeTitleField.bind(this)}
        />
        <TextField
          label="Software Name"
          required={false}
          value={(this.state.SoftwareListItem.SoftwareName).toString()}
          styles={textFieldStyles}
          onChange={this.onChangeSoftwareNameField.bind(this)}
        />
        <TextField
          label="Software Description"
          required={false}
          value={(this.state.SoftwareListItem.SoftwareDescription).toString()}
          styles={textFieldStyles}
          onChange={this.onChangeDescriptionField.bind(this)}
        />
        <TextField
          label="Software Version"
          required={false}
          value={(this.state.SoftwareListItem.SoftwareVersion).toString()}
          styles={textFieldStyles}
          onChange={this.onChangeSoftwareVersionField.bind(this)}
        />
        <Dropdown
          componentRef={dropdownRef}
          placeholder="select an option"
          label="Software Vendor"
          options={[
            { key: 'Microsoft', text: 'Microsoft' },
            { key: 'Sun', text: 'Sun' },
            { key: 'Oracle', text: 'Oracle' },
            { key: 'Google', text: 'Google' }
          ]}
          defaultSelectedKey={this.state.SoftwareListItem.SoftwareVendor}
          required
          styles={narrowDropdownStyles}
          onChange={this.onChangeDropDownField.bind(this)}
        />
        <br/>
        <PrimaryButton
          text='Add'
          title='Add'
          onClick={this.btnAdd_click}
        />
        &nbps;
        <PrimaryButton
          text='Update'
          title='Update'
          onClick={this.btnUpdate_click}
        />
        &nbps;
        <PrimaryButton
          text='Delete'
          title='Delete'
          onClick={this.btnDelete_click}
        />
        <br/>
        <div id="divStatus">
          {this.state.status}
        </div>

        <p className={styles.title}>
          <div>
            <DetailsList
              items={this.state.SoftwareListItems}
              columns={_softwareListColumns}
              setKey='Id'
              checkboxVisibility={CheckboxVisibility.always}
              selectionMode={SelectionMode.single}
              layoutMode={DetailsListLayoutMode.fixedColumns}
              compact={true}
              selection={this._selection}

            />
          </div>
        </p>
      </div>
    );
  }
}


Comments

Popular posts from this blog

Powerapps overcome 2000 item limit from any datasource

PowerApps multiselect cascading dropdown and save an item to SharePoint List

Multi select cascading dropdown in Power Apps