Create solution in the name of SpfxCrud.
/* eslint-disable @typescript-eslint/no-floating-promises */
/* eslint-disable react/self-closing-comp */
import * as React from 'react';
import styles from './SpfxCrud.module.scss';
import { ISpfxCrudProps } from './ISpfxCrudProps';
import { escape } from '@microsoft/sp-lodash-subset';
import {
SPHttpClient,
SPHttpClientResponse
} from '@microsoft/sp-http';
export default class SpFxCrud extends React.Component<ISpfxCrudProps, {}> {
public render(): React.ReactElement<ISpfxCrudProps> {
return (
<div className={styles.spfxCrud}>
<div className={styles.container}>
<div className={styles.row}>
<div className={styles.column}>
<p className={styles.description}>{escape(this.props.description)}</p>
<div className={styles.itemField}>
<div className={styles.fieldLabel}>Item ID:</div>
<input type="text" id='itemId'></input>
</div>
<div className={styles.itemField}>
<div className={styles.fieldLabel}>Full Name</div>
<input type="text" id='fullName'></input>
</div>
<div className={styles.itemField}>
<div className={styles.fieldLabel}>Age</div>
<input type="text" id='age'></input>
</div>
<div className={styles.itemField}>
<div className={styles.fieldLabel}>All Items:</div>
<div id="allItems"></div>
</div>
<div className={styles.buttonSection}>
<div className={styles.button}>
<span className={styles.label} onClick={this.createItem}>Create</span>
</div>
<div className={styles.button}>
<span className={styles.label} onClick={this.getItemById}>Read</span>
</div>
<div className={styles.button}>
<span className={styles.label} onClick={this.getAllItems}>Read All</span>
</div>
<div className={styles.button}>
<span className={styles.label} onClick={this.updateItem}>Update</span>
</div>
<div className={styles.button}>
<span className={styles.label} onClick={this.deleteItem}>Delete</span>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
// Create Item
private createItem = (): void => {
const body: string = JSON.stringify({
'Title': (document.getElementById("fullName")as HTMLInputElement).value,
'Age': (document.getElementById("age") as HTMLInputElement).value
});
this.props.context.spHttpClient.post(`${this.props.context.pageContext.web.absoluteUrl}/_api/web/lists/getbytitle('EmployeeDetails')/items`,
SPHttpClient.configurations.v1, {
headers: {
'Accept': 'application/json;odata=nometadata',
'Content-type': 'application/json;odata=nometadata',
'odata-version': ''
},
body: body
})
.then((response: SPHttpClientResponse) => {
if (response.ok) {
response.json().then((responseJSON) => {
console.log(responseJSON);
alert(`Item created successfully with ID: ${responseJSON.ID}`);
});
} else {
response.json().then((responseJSON) => {
console.log(responseJSON);
alert(`Something went wrong! Check the error in the browser console.`);
});
}
}).catch((error: any) => {
console.log(error);
});
}
// Get Item by ID
private getItemById = (): void => {
const id: number = parseInt((document.getElementById('itemId')! as HTMLInputElement).value, 10);
if (id > 0) {
this.props.context.spHttpClient.get(this.props.context.pageContext.web.absoluteUrl +`/_api/web/lists/getbytitle('EmployeeDetails')/items(${id})`,
SPHttpClient.configurations.v1,
{
headers: {
'Accept': 'application/json;odata=nometadata',
'odata-version': ''
}
})
.then((response: SPHttpClientResponse) => {
if (response.ok) {
response.json().then((responseJSON) => {
console.log(responseJSON);
(document.getElementById("fullName") as HTMLInputElement).value = responseJSON.Title;
(document.getElementById("age")as HTMLInputElement).value = responseJSON.Age;
// document.getElementById('fullName')['value'] = responseJSON.Title;
// document.getElementById('age')['value'] = responseJSON.Age;
});
} else {
response.json().then((responseJSON) => {
console.log(responseJSON);
alert(`Something went wrong! Check the error in the browser console.`);
});
}
}).catch((error: any) => {
console.log(error);
});
}
else {
alert(`Please enter a valid item id.`);
}
}
// Get all items
private getAllItems = (): void => {
this.props.context.spHttpClient.get(this.props.context.pageContext.web.absoluteUrl + `/_api/web/lists/getbytitle('EmployeeDetails')/items`,
SPHttpClient.configurations.v1,
{
headers: {
'Accept': 'application/json;odata=nometadata',
'odata-version': ''
}
})
.then((response: SPHttpClientResponse) => {
if (response.ok) {
response.json().then((responseJSON) => {
let html = `<table><tr><th>ID</th><th>Full Name</th><th>Age</th></tr>`;
responseJSON.value.map((item: { ID: any; Title: any; Age: any; }) => {
html += `<tr><td>${item.ID}</td><td>${item.Title}</td><td>${item.Age}</td></li>`;
});
html += `</table>`;
const allItemsElement = document.getElementById("allItems");
if (allItemsElement) {
allItemsElement.innerHTML = html;
} else {
console.error("Element with id 'allItems' not found.");
}
// document.getElementById("allItems").innerHTML = html;
console.log(responseJSON);
});
} else {
response.json().then((responseJSON) => {
console.log(responseJSON);
alert(`Something went wrong! Check the error in the browser console.`);
});
}
}).catch((error: any) => {
console.log(error);
});
}
// Update Item
private updateItem = (): void => {
const id: number = parseInt((document.getElementById('itemId')! as HTMLInputElement).value, 10);
const body: string = JSON.stringify({
'Title': (document.getElementById("fullName") as HTMLInputElement).value ,
'Age': (document.getElementById("age")as HTMLInputElement).value
});
if (id > 0) {
this.props.context.spHttpClient.post(`${this.props.context.pageContext.web.absoluteUrl}/_api/web/lists/getbytitle('EmployeeDetails')/items(${id})`,
SPHttpClient.configurations.v1,
{
headers: {
'Accept': 'application/json;odata=nometadata',
'Content-type': 'application/json;odata=nometadata',
'odata-version': '',
'IF-MATCH': '*',
'X-HTTP-Method': 'MERGE'
},
body: body
})
.then((response: SPHttpClientResponse) => {
if (response.ok) {
alert(`Item with ID: ${id} updated successfully!`);
} else {
response.json().then((responseJSON) => {
console.log(responseJSON);
alert(`Something went wrong! Check the error in the browser console.`);
});
}
}).catch((error: any) => {
console.log(error);
});
}
else {
alert(`Please enter a valid item id.`);
}
}
// Delete Item
private deleteItem = (): void => {
const id: number = parseInt((document.getElementById('itemId')! as HTMLInputElement).value, 10);
if (id > 0) {
this.props.context.spHttpClient.post(`${this.props.context.pageContext.web.absoluteUrl}/_api/web/lists/getbytitle('EmployeeDetails')/items(${id})`,
SPHttpClient.configurations.v1,
{
headers: {
'Accept': 'application/json;odata=nometadata',
'Content-type': 'application/json;odata=verbose',
'odata-version': '',
'IF-MATCH': '*',
'X-HTTP-Method': 'DELETE'
}
})
.then((response: SPHttpClientResponse) => {
if (response.ok) {
alert(`Item ID: ${id} deleted successfully!`);
}
else {
alert(`Something went wrong!`);
console.log(response.json());
}
});
}
else {
alert(`Please enter a valid item id.`);
}
}
}
SpfxCrud.module.scss
@import '~@fluentui/react/dist/sass/References.scss';
.spfxCrud {
overflow: hidden;
padding: 1em;
color: "[theme:bodyText, default: #323130]";
color: var(--bodyText);
&.teams {
font-family: $ms-font-family-fallbacks;
}
.container {
max-width: 700px;
margin: 0px auto;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.row {
@include ms-Grid-row;
@include ms-fontColor-white;
background-color: $ms-color-themeDark;
padding: 20px;
}
.column {
@include ms-Grid-col;
@include ms-lg10;
@include ms-xl8;
@include ms-xlPush2;
@include ms-lgPush1;
}
.title {
@include ms-font-xl;
@include ms-fontColor-white;
}
.subTitle {
@include ms-font-l;
@include ms-fontColor-white;
}
.description {
@include ms-font-l;
@include ms-fontColor-white;
}
.button {
// Our button
text-decoration: none;
height: 32px;
// Primary Button
min-width: 80px;
background-color: $ms-color-themePrimary;
border-color: $ms-color-themePrimary;
color: $ms-color-white;
// Basic Button
outline: transparent;
position: relative;
font-family: "Segoe UI WestEuropean", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
font-size: $ms-font-size-m;
font-weight: $ms-font-weight-regular;
border-width: 0;
text-align: center;
cursor: pointer;
display: inline-block;
margin: 10px;
.label {
font-weight: $ms-font-weight-semibold;
font-size: $ms-font-size-m;
height: 32px;
line-height: 32px;
margin: 0 4px;
vertical-align: top;
display: inline-block;
}
}
.itemField {
display: flex;
padding: 5px;
.fieldLabel {
min-width: 100px;
}
}
.buttonSection{
padding-top: 20px;
display: flex;
}
}
.welcome {
text-align: center;
}
.welcomeImage {
width: 100%;
max-width: 420px;
}
.links {
a {
text-decoration: none;
color: "[theme:link, default:#03787c]";
color: var(--link); // note: CSS Custom Properties support is limited to modern browsers only
&:hover {
text-decoration: underline;
color: "[theme:linkHovered, default: #014446]";
color: var(--linkHovered); // note: CSS Custom Properties support is limited to modern browsers only
}
}
}