SharePoint Framework – Fluent UI React ChoiceGroup (Radio Button) and Checkbox Example

In this SPFx tutorial, we will discuss how to use fluent UI react choicegroup or radio button and checkbox control in SharePoint framework client side web part.

In this example, we will create an SPFx web part and then we will add the fluent UI choice group and fluent UI react checkbox react control, and then finally, we will use how to save the values to a SharePoint Online list using PnP.

Also, I will explain, how to fix error, Error TS2307: Cannot find module ‘@fluentui/react’.

If you are new to fluent UI, check out What is Microsoft Fluent UI (with React) as well as I have you already have been set up your SPFx development environment.

[toc]

For this particular example, I have created a SharePoint Online list having below columns.

  • Title
  • SingleValueCheckbox
  • MultiValueCheckbox

And the list looks like below:

SPFx Fluent UI React ChoiceGroup and Checkbox Example
SPFx Fluent UI React ChoiceGroup and Checkbox Example

And here we are going to create a form like below:

SharePoint Framework Fluent UI React ChoiceGroup and Checkbox Example
SharePoint Framework Fluent UI React ChoiceGroup and Checkbox Example

Want to Learn SPFx development? Check out SharePoint Framework training course: https://www.spguides.com/sharepoint-framework-training/

A few things happening here:

  • First, the radio button values are populating from the SingleValueCheckbox column choice values, you can see the choices like below:
fluent ui choice group
fluent ui choice group
  • And, the spfx fluent ui checkbox values were populating from the MultiValueCheckbox column choice options.
spfx fluent ui checkbox
spfx fluent ui checkbox
  • Then finally on the button click the fluent ui radio button and fluent ui checkbox value will be saved to the SharePoint Online list using PnP.

SPFx fluent UI choice group and spfx fluent UI checkbox example

Here we will first create an SPFx react client side web part.

Open the nodejs command prompt and then create a directory in a location where you want to save the files.

md fluentuichoicedmo

cd fluentuichoicedmo

Then run the below command to start creating the spfx client side web part.

yo @microsoft/sharepoint

It will ask you the below things:

  • What is your solution name? Click on Enter to take the default name.
  • Which baseline packages do you want to target for your component (s)? Here choose one from the below options:
    • SharePoint Online only (latest)
    • SharePoint 2016 onwards, including 2019 and SharePoint Online
    • SharePoint 2019 onwards, including SharePoint Online

Here select SharePoint Online only (latest).

  • Where do you want to place the files? Choose one from the following:
    • Use the current folder
    • Create a subfolder with solution name

Here choose Use the current folder.

  • Do you to allow the tenant admin the choice of being able to deploy the solution to all sites immediately without running any feature deployment or adding apps in sites? Choose N.
  • Will the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant? Choose N.
  • Which type of client-side component to create? Choose WebPart from the below options:
    • WebPart
    • Extension
    • Library
  • What is your web part name? Give FluentUIChoiceDemo as the web part name
  • What is your web part description? Click on Enter to take the default name.
  • Which framework would you like to use? Choose React from the below options:
    • No JavaScript framework
    • React
    • Knockout
fluent ui choice group spfx
fluent ui choice group spfx

Then it will take sometime and then you can see a successful message like below:

fluent ui react checkbox
fluent ui react checkbox

Once we created the SPFx web part, we need to install fluentui/react. Below is the command:

npm install @fluentui/react
fluent ui react spfx checkbox
fluent ui react spfx checkbox

Then run the below command to install pnp, because here we are using PnP to save data to the SharePoint list.

npm i @pnp/sp

It will take some time and install pnp.

spfx fluent ui checkbox example
spfx fluent ui checkbox example

Next, run the below command to open the solution using visual studio code.

code .

Now, the solution looks like below:

fluent ui react spfx radio button
fluent ui react spfx radio button

Here, since the framework we are using a react framework, we will write mostly the code in the FluentUiChoiceDemo.tsx file.

Here, first we need to declare a variable that will hold the site URL. So I have added webURL properties in the IFluentUiChoiceDemoProps.ts file and the code looks like below:

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

And then in the web part file, FluentUiChoiceDemoWebPart.ts assign the value like below:

webURL:this.context.pageContext.web.absoluteUrl

The full code looks like below:

public render(): void {
    const element: React.ReactElement<IFluentUiChoiceDemoProps> = React.createElement(
      FluentUiChoiceDemo,
      {
        description: this.properties.description,
        webURL:this.context.pageContext.web.absoluteUrl
      }
    );

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

And now open the FluentUiChoiceDemo.tsx react component file and here we need to add the code to use the fluent ui choice group and fluent ui checkbox controls.

First add all the below import statements:

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';

Then add an interface like below:

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

Then add the constructor like below:

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

In the state we are setting up the default values to either empty or empty array:

Now, modify the render() method like below:

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

Here you can see the ChoiceGroup and the Checkbox control.

The fluent ui ChoiceGroup options are populating on this.state.singleValueOptions. And we are adding the fluent UI checkboxes based on the values in the this.state.multiValueOptions.

Here in the componentDidMount() method we are doing setState for the ChoiceGroup as well as for the Checkbox.

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

Then once user select the a radio button value or select multiple choices from the checkboxes, we are adding the values to the array.

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

The below method we are calling when user click on 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");
  }

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

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

gulp serve

In the local workbench you can see the web part will appear like below:

fluent ui react spfx choice group
fluent ui react spfx choice group

But we can not test this spfx client side web part in the local workbench.

Test SPFx web part locally

Now, to test the SPFx web part locally, while the local workbench is running, open the SharePoint Online site workbench. The URL will be like below:

https://tsinfotechnologies.sharepoint.com/sites/SPFxForBlog/_layouts/15/workbench.aspx

Note: The list should be there in this site.

Now, click on Add web part and you can see the web part.

spfx fluent ui choice group
spfx fluent ui choice group

Once you add the web part, you can see the web part added to the SharePoint workbench.

spfx fluent ui radio button checkbox
spfx fluent ui radio button checkbox

Here, you can select the option from the radio button and then select the checkbox options like below and click on the Submit button.

spfx fluent ui radio button
spfx fluent ui radio button

You can see the message, and if you will check the SharePoint Online list,

spfx fluent ui checkbox
spfx fluent ui checkbox

Deploy SPFx web part to Production

The above steps we saw to test the web part in the test environment, but if you want to deploy the web part to the production environment, then run the below commands.

gulp bundle --ship

gulp package-solution --ship

Once you run the above command, it will create the .sppkg file under the SharePoint folder like below:

spfx fluent ui checkbox example
spfx fluent ui checkbox example

Simply, upload this file into the tenant app catalog site or SharePoint site collection app catalog site. Then you can add the web part into a modern web part page in SharePoint Online.

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

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:

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.

SharePoint Framework – Fluent UI React ChoiceGroup (Radio Button) and Checkbox Example (Video Tutorial)

I have also created a video tutorial on how to use the Fluent UI React ChoiceGroup (Radio Button) and Fluent UI React Checkbox control in SPFx client-side web part.

Subscribe to our YouTube channel for more free videos.

Download SPFx Solution

You may like the following SPFx tutorials:

Conclusion

In this SharePoint framework tutorial, we learned how to use fluent ui choice group (fluent ui radio button) and fluent ui react checkbox control inside SPFx client-side web part. In an example, we saw how to save fluent ui react checkbox and fluent ui react radio button value into a SharePoint Online list using PnP. Also, we saw how to fix the error, Error TS2307: Cannot find module ‘@fluentui/react’.

>