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

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’.


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


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


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


  • And, the spfx fluent ui checkbox values were populating from the MultiValueCheckbox column choice options.


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:

1. SharePoint Online only (latest)

2. SharePoint 2016 onwards, including 2019 and SharePoint Online

3. 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:

1. Use the current folder

2. 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:

1. WebPart

2. Extension

3. 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:

1. No JavaScript framework

2. React

3. Knockout



fluent ui choice group spfx


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



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


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


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


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


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


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



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


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


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


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’


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.



Source: SP Guide


The Tech Platform

www.thetechplatform.com

0 comments