top of page
Writer's pictureManpreet Singh

Create Radio Buttons and Checkboxes with Fluent UI React in SharePoint Framework

In this tutorial, we will walk through the process of creating an SPFx web part. We will incorporate the Fluent UI choice group and Fluent UI react checkbox controls into our web part. Finally, we will demonstrate how to save the values to a SharePoint Online list using PnP.


Fluent UI Choice Group and Fluent UI Checkbox are components provided by Microsoft’s Fluent UI library, which is used to build user interfaces in a variety of Microsoft products.

  1. Fluent UI Choice Group: The Choice Group component, also known as radio buttons, lets users select one option from two or more choices. Each option is represented by one ChoiceGroup button; a user can select only one ChoiceGroup in a button group. In Fluent UI v9, ChoiceGroup is replaced with RadioGroup.

  2. Fluent UI Checkbox: The Checkbox component allows users to select one or more items from a group, or switch between two mutually exclusive options (checked or unchecked). It provides a way for users to make selections and toggle settings on or off.


Both components are part of the Fluent UI React library and can be used in SharePoint Framework (SPFx) web parts for SharePoint Online. They are designed to fit seamlessly into Microsoft 365.


Let’s start by creating a SharePoint list. To do this, navigate to “Site Columns => + New => List”.



SharePoint List


Next, we need to add the following columns to our list:

  • Title

  • Single Value Checkbox

  • Multi-Value Checkbox


To add a column to the SharePoint List, click on “+ Add Columns”. Enter the name of the column, select the type as “Choice”, and then click “Save”.

Add column to the SharePoint List


Add Column to SharePoint List 2

Your list should now look something like this:

SharePoint List 2


Create Radio Buttons and Checkboxes with Fluent UI React in SharePoint Framework

To create an SPFx web part example with Fluent UI ChoiceGroup and Fluent UI Checkbox, follow these steps:


Setting Up the Development Environment:

Open the Node.js command prompt.


Create a new directory for the project:

md fluentuichoicedmo
cd fluentuichoicedmo

Initialize the SPFx project:

yo @microsoft/sharepoint
  • Solution name: Enter

  • Baseline packages: Choose SharePoint Online only (latest)

  • File location: Use the current folder

  • Tenant admin deployment choice: N

  • Permissions for web APIs: N

  • Type of component: WebPart

  • Web part name: FluentUIChoiceDemo

  • Description: Enter

  • Framework: Choose React


Installing Dependencies:


Install Fluent UI React Package:

npm install @fluentui/react

Install PnP package for SharePoint interactions:

npm i @pnp/sp

Once you've completed these steps, you'll have set up your SPFx project with the necessary dependencies to integrate Fluent UI components and interact with SharePoint using PnP.



Setting Up Web Part Properties:


STEP 1: Define Interface in IFluentUiChoiceDemoProps.ts

In the IFluentUiChoiceDemoProps.ts file, define the interface IFluentUiChoiceDemoProps with a webURL property along with a description property:

export interface IFluentUiChoiceDemoProps {
  description: string;
  webURL:string;
}

STEP 2: Assign WebURL Property

In FluentUiChoiceDemoWebPart.ts, assign the webURL property the value of the current SharePoint site URL:

webURL:this.context.pageContext.web.absoluteUrl

This ensures that the web part knows the SharePoint site URL it's deployed to.


Implementing React Component (FluentUiChoiceDemo.tsx):


STEP 1: Import Necessary Modules

Modules include Fluent UI components for UI elements like checkboxes and choice groups, as well as PnP.js for SharePoint operations.

import { Guid } from '@microsoft/sp-core-library';
import { sp, Web, IWeb } from "@pnp/sp/presets/all";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import {Checkbox, Label, PrimaryButton, ChoiceGroup, IChoiceGroupOption} from '@fluentui/react';
  • Guid: This module is imported from @microsoft/sp-core-library for generating GUIDs.

  • sp, Web, IWeb: These modules are imported from @pnp/sp/presets/all for SharePoint operations.

  • "@pnp/sp/lists" and "@pnp/sp/items": These modules are imported to work with SharePoint lists and items.

  • Checkbox, Label, PrimaryButton, ChoiceGroup, IChoiceGroupOption: These modules are imported from @fluentui/react for UI components.


STEP 2: Define Interface for Component State

This step defines a TypeScript interface named ICheckboxStates to manage the component's state.

export interface ICheckboxStates
{
  singleValueChoiceGroup:string;
  multiValueCheckbox:any;
  singleValueOptions:any;
  multiValueOptions:any;
}

The interface specifies properties to hold values for single-select choice groups, multi-select checkboxes, and their respective options.


STEP 3: Implement Constructor

Here, a constructor is implemented to initialize the component's state.

constructor(props)
  {
    super(props);
    this.state = {
      singleValueChoiceGroup:"",
      multiValueCheckbox:[],
      singleValueOptions:[],
      multiValueOptions:[]
    };
    
  }

The constructor sets default values for the state properties defined in the ICheckboxStates interface.


STEP 4: Implement Render Mode

The render() method is implemented to define how the component renders UI elements.

public render(): React.ReactElement<IFluentUiChoiceDemoProps> {
    return (
      <div className={ styles.fluentUiChoiceDemo }>
        <h1>Fluent UI ChoiceGroup & Checkbox</h1>
        <div>
        <Label>Single Select ChoiceGroup</Label>
        <ChoiceGroup onChange={this._onChange} options={this.state.singleValueOptions} />
        </div>
        <div>
        <Label>Multi Select Checkbox</Label>
        {this.state.multiValueOptions.map((item) => {
          return (
            <div style={{margin:"2px",padding:"3px"}}>
              <Checkbox style={{margin:"2px",padding:"3px"}} label={item.label} onChange={this.onCheckboxMultiChecked} />
              </div>
            );
          }
        )}
        </div>
        <br />
          <PrimaryButton onClick={e => this.Save(e)}>Submit</PrimaryButton>
      </div>
    );
  }

JSX elements representing choice groups, checkboxes, labels, and a submit button are returned.


State values are used to populate options for choice groups and checkboxes.


STEP 6: Implement 'componentDidMount' method

The componentDidMount() lifecycle method is implemented to perform actions after the component is mounted.

public async componentDidMount(){
    var singleValue=await this.getCheckboxChoices("SingleValueCheckbox","singlevalue");
   this.setState({singleValueOptions:singleValue});
    var multiValue=await this.getCheckboxChoices("MultiValueCheckbox","multivalue");
   this.setState({multiValueOptions:multiValue});
  }
  
  public async getCheckboxChoices(fieldname,value) {
    if(value=="singlevalue")
    {
      var singlevaluechoices = [];
    let web = Web(this.props.webURL);
    await web.lists.getByTitle("FluentUICheckbox").fields.getByInternalNameOrTitle(fieldname).select('Choices').get().then((field) => {
      console.log(field);
      for (var i = 0; i < field["Choices"].length; i++) {
        singlevaluechoices.push({
          key: field["Choices"][i],
          text: field["Choices"][i]
        });
      }

    });
     return  singlevaluechoices;
    }
    else if(value=="multivalue")
    {
      var multivaluechoices = [];
    let web = Web(this.props.webURL);
    await web.lists.getByTitle("FluentUICheckbox").fields.getByInternalNameOrTitle(fieldname).select('Choices').get().then((field) => {
      console.log(field);
      for (var i = 0; i < field["Choices"].length; i++) {
        multivaluechoices.push({
          label: field["Choices"][i]
        });
      }
    });
     return  multivaluechoices;
    }
  }

In this case, it fetches choice options from SharePoint lists and updates the component's state accordingly.


STEP 7: Implement Event Handlers

Event handlers such as _onChange and onCheckboxMultiChecked are implemented to handle user interactions.

public _onChange = async (ev: React.FormEvent<HTMLInputElement>, option: IChoiceGroupOption): Promise<void> => {
    console.log(option);
    this.setState({ singleValueChoiceGroup: option.key });
  }

  public onCheckboxMultiChecked = async (ev: React.FormEvent<HTMLElement>, isChecked: boolean): Promise<void> => {
    if (arr.indexOf(ev.currentTarget["ariaLabel"]) !== -1) {
      arr.splice(arr.indexOf(ev.currentTarget["ariaLabel"]), 1);
    }
    else {
      await arr.push(ev.currentTarget["ariaLabel"]);
    }
    await this.setState({ multiValueCheckbox: arr });
  }

_onChange: This method handles changes in the choice group and updates the singleValueChoiceGroup state.


onCheckboxMultiChecked: This method handles changes in the multi-select checkboxes and updates the multiValueCheckbox state.



STEP 8: Implement Save Method

The Save() method is implemented to handle saving selected values to the SharePoint list when the user clicks the submit button.

private async Save(e) {
    let web = Web(this.props.webURL);
    await web.lists.getByTitle("FluentUICheckbox").items.add({
      Title: Guid.newGuid().toString(),
      SingleValueCheckbox: this.state.singleValueChoiceGroup,
      MultiValueCheckbox: { results: this.state.multiValueCheckbox }

    }).then(i => {
      console.log(i);
    });
    alert("Submitted Successfully");
  }

It utilizes PnP.js to interact with SharePoint lists and add new items containing the selected values..


The complete code looks like below: (FluentUiChoiceDemo.tsx)

import * as React from 'react';
import styles from './FluentUiChoiceDemo.module.scss';
import { IFluentUiChoiceDemoProps } from './IFluentUiChoiceDemoProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { Guid } from '@microsoft/sp-core-library';
import { sp, Web, IWeb } from "@pnp/sp/presets/all";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import {Checkbox, Label, PrimaryButton, ChoiceGroup, IChoiceGroupOption} from '@fluentui/react';

var arr = [];
export interface ICheckboxStates
{
  singleValueChoiceGroup:string;
  multiValueCheckbox:any;
  singleValueOptions:any;
  multiValueOptions:any;
}

export default class FluentUiChoiceDemo extends React.Component<IFluentUiChoiceDemoProps, ICheckboxStates> {
  constructor(props)
  {
    super(props);
    this.state = {
      singleValueChoiceGroup:"",
      multiValueCheckbox:[],
      singleValueOptions:[],
      multiValueOptions:[]
    };
    
  }
  public async componentDidMount(){
    var singleValue=await this.getCheckboxChoices("SingleValueCheckbox","singlevalue");
   this.setState({singleValueOptions:singleValue});
    var multiValue=await this.getCheckboxChoices("MultiValueCheckbox","multivalue");
   this.setState({multiValueOptions:multiValue});
  }
  
  public async getCheckboxChoices(fieldname,value) {
    if(value=="singlevalue")
    {
      var singlevaluechoices = [];
    let web = Web(this.props.webURL);
    await web.lists.getByTitle("FluentUICheckbox").fields.getByInternalNameOrTitle(fieldname).select('Choices').get().then((field) => {
      console.log(field);
      for (var i = 0; i < field["Choices"].length; i++) {
        singlevaluechoices.push({
          key: field["Choices"][i],
          text: field["Choices"][i]
        });
      }

    });
     return  singlevaluechoices;
    }
    else if(value=="multivalue")
    {
      var multivaluechoices = [];
    let web = Web(this.props.webURL);
    await web.lists.getByTitle("FluentUICheckbox").fields.getByInternalNameOrTitle(fieldname).select('Choices').get().then((field) => {
      console.log(field);
      for (var i = 0; i < field["Choices"].length; i++) {
        multivaluechoices.push({
          label: field["Choices"][i]
        });
      }
    });
     return  multivaluechoices;
    }
  }
  public _onChange = async (ev: React.FormEvent<HTMLInputElement>, option: IChoiceGroupOption): Promise<void> => {
    console.log(option);
    this.setState({ singleValueChoiceGroup: option.key });
  }

  public onCheckboxMultiChecked = async (ev: React.FormEvent<HTMLElement>, isChecked: boolean): Promise<void> => {
    if (arr.indexOf(ev.currentTarget["ariaLabel"]) !== -1) {
      arr.splice(arr.indexOf(ev.currentTarget["ariaLabel"]), 1);
    }
    else {
      await arr.push(ev.currentTarget["ariaLabel"]);
    }
    await this.setState({ multiValueCheckbox: arr });
  }

  private async Save(e) {
    let web = Web(this.props.webURL);
    await web.lists.getByTitle("FluentUICheckbox").items.add({
      Title: Guid.newGuid().toString(),
      SingleValueCheckbox: this.state.singleValueChoiceGroup,
      MultiValueCheckbox: { results: this.state.multiValueCheckbox }

    }).then(i => {
      console.log(i);
    });
    alert("Submitted Successfully");
  }

  public render(): React.ReactElement<IFluentUiChoiceDemoProps> {
    return (
      <div className={ styles.fluentUiChoiceDemo }>
        <h1>Fluent UI ChoiceGroup and Checkbox</h1>
        <div>
        <Label>Single Value ChoiceGroup</Label>
        <ChoiceGroup onChange={this._onChange} options={this.state.singleValueOptions} />
        </div>
        <div>
        <Label>Multi Value Checkbox</Label>
        {this.state.multiValueOptions.map((item) => {
          return (
            <div style={{margin:"2px",padding:"3px"}}>
              <Checkbox style={{margin:"2px",padding:"3px"}} label={item.label} onChange={this.onCheckboxMultiChecked} />
              </div>
            );
          }
        )}
        </div>
        <br />
          <PrimaryButton onClick={e => this.Save(e)}>Submit</PrimaryButton>
      </div>
    );
  }
}

Now, it is time to run the below command and start the local workbench.

gulp serve


Troubleshooting

If you get an error, Error TS2307: Cannot find module ‘@fluentui/react’ while running the gulp serve command, then run the below command to fix the error:

npm install @fluentui/react


You can see like below:

SharePoint - Error TS2307: Cannot find module ‘@fluentui/react’

Error TS2307: Cannot find module ‘@fluentui/react’


You can install using yarn like below:

yarn add @fluentui/react

Once you run the above npm cmdlets the error Error TS2307: Cannot find module ‘@fluentui/react’ will not come.



Conclusion

By following this tutorial, you've learned how to create an SPFx web part using Fluent UI controls like ChoiceGroup and Checkbox, integrate SharePoint interactions using PnP, and deploy the web part for production use. This provides a foundation for building interactive and user-friendly SharePoint solutions.

Comments


bottom of page