How To Use FilePicker Control Of PnP In SPFx Webpart

Background

With the recent popularity of SPFx, developers are required to develop some complex requirements using the SharePoint framework web part. Many of these requirements are common and need to be developed again and again. Microsoft has provided Office UI fabric react-based controls which can be easily used in our SPFx web part. Still, some controls are missing in Office UI fabric, thanks to our awesome PnP initiative, the community has stepped forward and developed many more controls that can be used in our SPFx solutions.

You can know and read about all the controls available from the PnP controls library at this link. Today, we are going to learn one of these controls 'File Picker control', and how to use it in our SPFx web part.

File picker control allows us to browse and select a file from various places. Please check this link for more details.

Currently supported locations

  • Recent files: The Tab allows selecting a file from recently modified files based on the search results.
  • Web search: Tab uses Bing cognitive services to look for a file. (Only images)
  • OneDrive: The tab allows selecting a file from the user's OneDrive.
  • Site document libraries: The Tab allows selecting a file from the existing site document libraries.
  • Upload: The tab allows uploading a file from a local drive.
  • From a link: The Tab allows pasting a link to the document.

Let's get started and create the web part.

Step 1. Create SPFx solution and web part

Run the below commands in sequence.

Open a node js command prompt and create a directory for the SPFx solution.

md PnPControlsDemo  
cd PnPControlsDemo 

Let us now create an SPFx solution and add the web part to it.

  1. yo @microsoft/sharepoint

select below options

Select below options

Once you select all options in the wizard one by one, it will take some time to generate the code structure.

Generate the code

Now let us install the required npm packages to use PnP controls and run the below command.

npm install @pnp/spfx-controls-react --save  

After it is completed, open the same folder in Visual Studio code( you can use any other editor also).

Now let us modify the code to use these controls.

Step 2. Passing WebPart context to React components

File picker requires Sharepoint site context to work with, hence we will pass it from our web part file to react components.

Open src\webparts\controls\components\IControlsProps.ts

Modify the code below.

import { WebPartContext } from '@microsoft/sp-webpart-base';
export interface IControlsProps {
  description: string;
  context: WebPartContext;
}

Open src\webparts\controls\ControlsWebPart.ts

Modify the render method to pass context.

public render(): void {
  const element: React.ReactElement<IControlsProps> = React.createElement(
    Controls,
    {
      description: this.properties.description,
      context: this.context
    }
  );
  ReactDom.render(element, this.domElement);
}

Please note we have just added the line 'context:this.context'.

Step 3. Modify the React component associated with Webpart

Open src\webparts\controls\components\Controls.tsx

Import file picker control

import { FilePicker, IFilePickerResult } from '@pnp/spfx-controls-react/lib/FilePicker';

Create an Interface to Store State, and add below code below the last import statement.

export interface IControlsState {
  filePickerResult: any;
}

Modify the component as below.

export default class Controls extends React.Component<IControlsProps, IControlsState> {
  constructor(props: IControlsProps, state: IControlsState) {
    super(props);
    this.state = { filePickerResult: null };
  }
  // Additional class methods and components would go here...
}

Modify the render method

Add the below code as per your requirement.

<FilePicker
  buttonLabel="Select File"
  onSave={(filePickerResult: IFilePickerResult) => {
    this.setState({ filePickerResult });
    alert(JSON.stringify(this.state.filePickerResult));
  }}
  onChanged={(filePickerResult: IFilePickerResult) => {
    this.setState({ filePickerResult });
    alert(JSON.stringify(this.state.filePickerResult));
  }}
  context={this.props.context}
/>

Below is what the final render method looks like for my sample.

If you look closely, we are using the save and unchanged methods to capture select file results, set state, and then alert the object by stringify. This is just to demonstrate what object is returned as a selected file. Please note that this will not return base64 or the actual image but only the path to the selected file.

public render(): React.ReactElement<IControlsProps> {
  return (
    <div className={styles.controls}>
      <div className={styles.container}>
        <div className={styles.row}>
          <div className={styles.column}>
            <span className={styles.title}>Welcome to SharePoint!</span>
            <p className={styles.subTitle}>Customize SharePoint experiences using Web Parts.</p>
            <p className={styles.description}>{escape(this.props.description)}</p>
            <a href="https://aka.ms/spfx" className={styles.button}>
              <span className={styles.label}>Learn more</span>
            </a>
          </div>
        </div>
      </div>
      <br />
      <FilePicker
        buttonLabel="Select File"
        onSave={(filePickerResult: IFilePickerResult) => {
          this.setState({ filePickerResult });
          alert(JSON.stringify(this.state.filePickerResult));
        }}
        onChanged={(filePickerResult: IFilePickerResult) => {
          this.setState({ filePickerResult });
          alert(JSON.stringify(this.state.filePickerResult));
        }}
        context={this.props.context}
      />
    </div>
  );
}

We are done with the code, now let us run it. Use the gulp serve command in the node js command prompt. please note that as this control requires the ext of the SharePoint site because it has to display lists and libraries from SharePoint. So we will test this web part in SharePoint workbench

Once, the local workbench is opened in the browser, open SharePoint workbench.

https://amazonprime.sharepoint.com/sites/familyman/_layouts/15/workbench.aspx

Below is the output of the web part.

Welcome to share point

Click on the Select file button, and we will see below panel opening below.

I have selected Site from the left tab.

Selected site

Click on any document library and we will get a list of files inside that document library.

Justice leagues's collaboration platform

Click on OneDrive, you will see a list of all files under the currently logged-in user's drive files.

Documents

Select any of the files and click on open, below is when I have selected a file from one of the library

Justice leagues's

If you look at the alert box, we can see it has returned us selected file path, filename, and filename without extension, etc. We can use this information to work as per our requirements.

Conclusion

This control can be very useful if we want an advanced file picker control, as HTML control will only allow us to select a file from a local machine. There are many configuration options available that can be used to show/hide tabs on the left or configure different options of this control.

Thanks for reading, hope this helps.

Happy coding..!!