How to Insert Data into a SharePoint Multi-Select Field Using SPFx?

If you are required to insert data into a SharePoint list multi-select choice field using SharePoint Framework client-side webpart, then this post will help you to achieve it.

This spfx tutorial will demonstrate step by step guide on how to insert data into a SharePoint multi-select field using spfx with an example.

For example, I have a SharePoint list called ‘Task Management,’ so I have three columns: Title, Assignee, and Assignment.

Here Assignments is the choice column(multi-selection is enabled). So, we will create a form based on these fields; when we click on submit, the data gets submitted to the list, like how we add data to the SharePoint list by default.

How to Insert Data into a SharePoint Multi-Select Field Using SPFx

Here we will see how to insert data to a SharePoint list multi-select field using spfx.

Before we start creating a solution, we need to build the SharePoint list; here is my SharePoint list ‘Task Management’, having the below columns:

  • Title– Single line of text
  • Assignee-Single line of text
  • Assignments– Choice(multi-selection enabled)
How to insert data into a SharePoint multi-select field using spfx
How to insert data into a SharePoint multi-select field using spfx

Let’s create the spfx solution like the one below by following the steps.

Using spfx clent webpart insert data into a SharePoint list multi-select choice field

Step 1: Create the project directory and navigate to the project directory by using the below command:

mkdir CreateSPListItem
cd CreateSPListItem

Step 2: Run the below command to build the solution inside the directory using yeoman SharePoint generator.

yo @microsoft/sharepoint

The yeomann SharePoint generator will ask you the list of questions:

  • ? What is your solution name? create-sp-list-item( provide the solution name)
  • ? Which type of client-side component to create? WebPart (here you can see four choices I.e. Webpart, Extension, Library, Adaptive Card Extension, and select Webpart)
  • ? What is your Web part name? CreateSPListItem (provide the webpart name)
  • ? Which template would you like to use? React(Select react, from  3 options :Minimal, React, No Framework)

Now it will take some time to download and install the dependencies required to create the solution. Once the spfx solution is created, you can see the below success message.

 insert data into a SharePoint multi-select field using spfx
insert data into a SharePoint multi-select field using spfx

Step 3: Then install some of the required libraries, which we will use in our solution.

Here are the required libraries we need to install for our spfx solution.

Install the Pnpjs library to interact with Sharepoint Online, for this run the below command:

npm install @pnp/sp@1.3.8 @pnp/odata@1.3.8 @pnp/logging@1.3.8 @pnp/common@1.3.8

Install the Bootstrap framework, which we will use for styling the form, run the below command:

npm install bootstrap

Step 4: Now open the solution in the code editor, here I am using VS code editor. To open the solution run the below command

code .

Once the solution is opened in the code editor, you can see the project structure below:

insert data into a SharePoint multi-select field using sharepoint framework
insert data into a SharePoint multi-select field using sharepoint framework

Step 5: Now navigate to .tsx file, located in the ‘src\webparts\createSpListItem\components\CreateSpListItem.tsx’.

In this file first, we will import the required files and components, which we will use in our solution.

import * as React from 'react';
import styles from './CreateSpListItem.module.scss';
import { sp } from '@pnp/sp';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min.js';

Step 6: Next, define an interface ‘ICreateItemState’. This interface defines the data types for the various characteristics that will be saved in the state of the component.

export interface ICreateItemState {
  title: string;
  assignee: string;
  assignments: string[];
  assignmentOptions: any,
  successMessage: string;

}

Step 7: Next, in the below code, the component class, which extends the React. Component class is defined. The interface specified above is used to initialize the state in the constructor method.

export default class CreateSpListItem extends React.Component<{}, ICreateItemState> {

  constructor(props: {}) {
    super(props);

    // Initialize the state
    this.state = {
      title: '',
      assignee: '',
      assignments: [], // Initialize to empty array
      assignmentOptions: [
        { label: 'Design', value: 'Design' },
        { label: 'Development', value: 'Development' },
        { label: 'Testing', value: 'Testing' },
        { label: 'Document', value: 'Document' },
      ],
      successMessage: '',


    };
  }
.....
....
}

Step 8: In the below code, sp.setup() method from PnP is overridden in the component’s componentDidMount() method to initialize the SharePoint context. By using the SharePoint context from the page, this method initializes the PnP library.

 public async componentDidMount(): Promise<void> {
    try {
      // Initialize SharePoint context
      await sp.setup({
        spfxContext: this.context.pageContext
      });
    } catch (error) {
      console.error('Error initializing SharePoint context:', error);
    }
  }

Step 9: Next, we will define methods to handle changes in the input field. These methods utilize React’s setState() method to update the component’s state.

 private onchangedTitle = (event: React.FormEvent<HTMLInputElement>): void => {

    this.setState({ title: event.currentTarget.value });

  }

  //handle  Assignee field

  private onchangedAssignee = (event: React.FormEvent<HTMLInputElement>): void => {

    this.setState({ assignee: event.currentTarget.value });
  }

Step 10: Next, define OnSubmit(), an event handler that handles form submissions. This method uses the PnP library to add the form data to a SharePoint list after retrieving data from the component’s state.

Errors are detected and logged to the console if any occur. The component’s state is changed to clear the form and provide a success message if the action is successful.

  private onSubmit = async (event: React.FormEvent<HTMLFormElement>): Promise<void> => {
    event.preventDefault();
    // Insert form data to SharePoint list
    const { title, assignee, assignments } = this.state;
    try {
      console.log(title);
      console.log(assignee);
      console.log(assignments);

      const list = await sp.web.lists.getByTitle('TaskManagement').items.get();
      console.log(list);
      await sp.web.lists.getByTitle('TaskManagement').items.add({
        Title: title,
        Assignee: assignee,
        Assignments:  { results: assignments }
      });
      this.setState({
        title: '',
        assignee: '',
        assignments: [],
        successMessage: 'Data added to SharePoint list successfully!',
      });
    } catch (error) {
      console.error('Error adding data to SharePoint list:', error);
    }
  };

Step 11: Next, define the ‘onCloseSuccessMessage’, as a class method, that sets the state of the success message to an empty string, when called.

  private onCloseSuccessMessage = (): void => {
    this.setState({ successMessage: '' });
  };

Step 12: This React component displays a form for inserting data into a SharePoint List using render(). The component has various form fields, including checkboxes for Title, Assignee, and Assignments. When the Submit button is clicked, the onSubmit event is activated.

Now change the render method with the below code:

public render(): React.ReactElement<{}> {
    const { title, assignee, successMessage } = this.state;
    return (
      <section className={`${styles.createSpListItem} `}>
        <div className="container">
          <h1>Add Data to SharePoint List</h1>
          {successMessage && (
            <div className="alert alert-success alert-dismissible fade show" role="alert">
              <span>{successMessage}</span>
              <button type="button" className="close" onClick={this.onCloseSuccessMessage}>
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
          )}
          <form onSubmit={this.onSubmit} >
  
            <div className="form-group">
              <label htmlFor="title">Title:</label>
              <input type="text" className="form-control" id="title" value={title} onChange={this.onchangedTitle} />
            </div>
  
            <div className="form-group">
              <label htmlFor="assignee">Assignee:</label>
              <input type="text" className="form-control" id="assignee" value={assignee} onChange={this.onchangedAssignee} />
            </div>
  
            <div className="form-group">
              <label>Assignments:</label>
              <div>
                {this.state.assignmentOptions.map((option: any) => (
                  <div key={option.value} className="form-check">
                    <input
                      type="checkbox"
                      className="form-check-input"
                      id={option.value}
                      name="assignments"
                      value={option.value}
                      checked={this.state.assignments.includes(option.value)}
                      onChange={(event) => {
                        const isChecked = event.target.checked;
                        if (isChecked) {
                          this.setState((prevState) => ({
                            assignments: [...prevState.assignments, option.value],
                          }));
                        } else {
                          this.setState((prevState) => ({
                            assignments: prevState.assignments.filter(
                              (value) => value !== option.value
                            ),
                          }));
                        }
                      }}
                    />
                    <label className="form-check-label" htmlFor={option.value}>{option.label}</label>
                  </div>
                ))}
              </div>
            </div>
  
            <button type="submit" className="btn btn-primary">Submit</button>
  
          </form>
        </div>
      </section>
    );
  }

Here is the explanation for the above render() code:

  • The class component defines a state object with the following properties: title, assignee, and successMessage.
  • The state object’s values for these properties are destructured and assigned to constants in the render method.
  • The return statement includes JSX describing the component’s structure and content.
  • The class ‘createSpListItem’ for the section element is specified in a different stylesheet imported into the component.
  • A div element with the class container contains the form inside the section element.
  • The form’s header is shown in the h1 element.
  • A ternary operator is used to display the successMessage property conditionally. If it does, a success class alert div element is displayed.
  • Data submission to the SharePoint list is handled by the form element. It has a onSubmit event handler that causes the component’s onSubmit method to be called.
  • Next, there are three input fields: Title, Assignee, and Assignments. OnChange event handlers for the title and assignee text input fields change the respective state properties. The assignments field consists of a collection of dynamically generated checkboxes from an array of objects with value and label characteristics.
  • Each checkbox’s checked attribute is determined by whether the relevant value is present in the assignments array in the component state.
  • Based on whether a checkbox is selected or unchecked, the component state’s assignments array is updated by each checkbox’s onChange event handler.
  • At last, when the submit button is clicked, the onSubmit() is called.

Here is the full code, for the .tsx file:

import * as React from 'react';
import styles from './CreateSpListItem.module.scss';
import { sp } from '@pnp/sp';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min.js';


export interface ICreateItemState {
  title: string;
  assignee: string;
  assignments: string[];
  assignmentOptions: any,
  successMessage: string;

}

export default class CreateSpListItem extends React.Component<{}, ICreateItemState> {

  constructor(props: {}) {
    super(props);

    // Initialize the state
    this.state = {
      title: '',
      assignee: '',
      assignments: [], // Initialize to empty array
      assignmentOptions: [
        { label: 'Design', value: 'Design' },
        { label: 'Development', value: 'Development' },
        { label: 'Testing', value: 'Testing' },
        { label: 'Document', value: 'Document' },
      ],
      successMessage: '',


    };
  }

  public async componentDidMount(): Promise<void> {
    try {
      // Initialize SharePoint context
      await sp.setup({
        spfxContext: this.context.pageContext
      });
    } catch (error) {
      console.error('Error initializing SharePoint context:', error);
    }
  }

  private onchangedTitle = (event: React.FormEvent<HTMLInputElement>): void => {

    this.setState({ title: event.currentTarget.value });

  }

  //handle  Assignee field

  private onchangedAssignee = (event: React.FormEvent<HTMLInputElement>): void => {

    this.setState({ assignee: event.currentTarget.value });
  }

//handle te form submission
  private onSubmit = async (event: React.FormEvent<HTMLFormElement>): Promise<void> => {
    event.preventDefault();
    // Insert form data to SharePoint list
    const { title, assignee, assignments } = this.state;
    try {
      console.log(title);
      console.log(assignee);
      console.log(assignments);

      const list = await sp.web.lists.getByTitle('TaskManagement').items.get();
      console.log(list);
      await sp.web.lists.getByTitle('TaskManagement').items.add({
        Title: title,
        Assignee: assignee,
        Assignments:  { results: assignments }
      });
      this.setState({
        title: '',
        assignee: '',
        assignments: [],
        successMessage: 'Data added to SharePoint list successfully!',
      });
    } catch (error) {
      console.error('Error adding data to SharePoint list:', error);
    }
  };

  // set the success message

  private onCloseSuccessMessage = (): void => {
    this.setState({ successMessage: '' });
  };


  public render(): React.ReactElement<{}> {
    const { title, assignee, successMessage } = this.state;
    return (
      <section className={`${styles.createSpListItem} `}>
        <div className="container">
          <h1>Add Data to SharePoint List</h1>
          {successMessage && (
            <div className="alert alert-success alert-dismissible fade show" role="alert">
              <span>{successMessage}</span>
              <button type="button" className="close" onClick={this.onCloseSuccessMessage}>
                <span aria-hidden="true">&times;</span>
              </button>
            </div>
          )}
          <form onSubmit={this.onSubmit} >
  
            <div className="form-group">
              <label htmlFor="title">Title:</label>
              <input type="text" className="form-control" id="title" value={title} onChange={this.onchangedTitle} />
            </div>
  
            <div className="form-group">
              <label htmlFor="assignee">Assignee:</label>
              <input type="text" className="form-control" id="assignee" value={assignee} onChange={this.onchangedAssignee} />
            </div>
  
            <div className="form-group">
              <label>Assignments:</label>
              <div>
                {this.state.assignmentOptions.map((option: any) => (
                  <div key={option.value} className="form-check">
                    <input
                      type="checkbox"
                      className="form-check-input"
                      id={option.value}
                      name="assignments"
                      value={option.value}
                      checked={this.state.assignments.includes(option.value)}
                      onChange={(event) => {
                        const isChecked = event.target.checked;
                        if (isChecked) {
                          this.setState((prevState) => ({
                            assignments: [...prevState.assignments, option.value],
                          }));
                        } else {
                          this.setState((prevState) => ({
                            assignments: prevState.assignments.filter(
                              (value) => value !== option.value
                            ),
                          }));
                        }
                      }}
                    />
                    <label className="form-check-label" htmlFor={option.value}>{option.label}</label>
                  </div>
                ))}
              </div>
            </div>
  
            <button type="submit" className="btn btn-primary">Submit</button>
  
          </form>
        </div>
      </section>
    );
  }
  
}

Step 13: Next, navigate to .ts file, located in the ‘src\webparts\createSpListItem\CreateSpListItemWebPart.ts’, . Here change the code with the below 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 { IReadonlyTheme } from '@microsoft/sp-component-base';

import * as strings from 'CreateSpListItemWebPartStrings';
import CreateSpListItem from './components/CreateSpListItem';
import { ICreateSpListItemProps } from './components/ICreateSpListItemProps';

export interface ICreateSpListItemWebPartProps {
  description: string;
}

export default class CreateSpListItemWebPart extends BaseClientSideWebPart<ICreateSpListItemWebPartProps> {



  public async render(): Promise< void> {
    const element: React.ReactElement<ICreateSpListItemProps> = React.createElement(
      CreateSpListItem
      
    );

    await ReactDom.render(element, this.domElement);
  }

  protected onInit(): Promise<void> {
    return this._getEnvironmentMessage().then(message => {
      
    });
  }



  private _getEnvironmentMessage(): Promise<string> {
    if (!!this.context.sdks.microsoftTeams) { // running in Teams, office.com or Outlook
      return this.context.sdks.microsoftTeams.teamsJs.app.getContext()
        .then(context => {
          let environmentMessage: string = '';
          switch (context.app.host.name) {
            case 'Office': // running in Office
              environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOffice : strings.AppOfficeEnvironment;
              break;
            case 'Outlook': // running in Outlook
              environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOutlook : strings.AppOutlookEnvironment;
              break;
            case 'Teams': // running in Teams
              environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentTeams : strings.AppTeamsTabEnvironment;
              break;
            default:
              throw new Error('Unknown host');
          }

          return environmentMessage;
        });
    }

    return Promise.resolve(this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentSharePoint : strings.AppSharePointEnvironment);
  }

  protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void {
    if (!currentTheme) {
      return;
    }

   
    const {
      semanticColors
    } = currentTheme;

    if (semanticColors) {
      this.domElement.style.setProperty('--bodyText', semanticColors.bodyText || null);
      this.domElement.style.setProperty('--link', semanticColors.link || null);
      this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered || null);
    }

  }

  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
                })
              ]
            }
          ]
        }
      ]
    };
  }
}

Step 14: Then change the code with the below code in the ‘ICreateSpListItemProps.ts’ file located in the ‘src\webparts\createSpListItem\components\ICreateSpListItemProps.ts’.

export interface ICreateSpListItemProps {

}

Step 15: Now we will configure the local server workbench, so for this navigate to server.json, which is located in the ‘ config\serve.json’. Then provide the SharePoint site, to ‘initialPage’ properties like below:

insert data into a SharePoint multi-select field using sharepoint framework client webpart
insert data into a SharePoint multi-select field using Sharepoint framework client webpart

Step 16: To run the solution in the local server workbench, run the below command:

gulp serve

Once you run the command, it will take you to the browser, and click on the Add icon -> select the webpart under Local.

Using spfx insert data into a SharePoint multi-select field
Using spfx insert data into a SharePoint multi-select field

Now you can see the form is rendered, provide the input to the field, and click on submit.

Using spfx clent webpart insert data into a SharePoint multi-select field
Using spfx clent webpart insert data into a SharePoint multi-select field

You can see the data get submitted to the SharePoint list, as by default we save when we create an item in the SharePoint list.

Using spfx clent webpart insert data into a SharePoint list multi-select field
Using spfx clent webpart insert data into a SharePoint list multi-select field

This is how we can save data SharePoint list choice multi-select field using spfx client webpart.

Download the Solution

To download the solution, click on the link, then unzip the folder, and run the below command:

npm i

Conclusion

In this spfx tutorial, we saw how to insert data into a SharePoint multi-select field using spfx.

Also, you may like some more SPFx tutorials:

Bind SharePoint List Items to SPFx fluent ui react dropdown