SPFx React Controls – ListView Control

My best SPFx React Control is ListView Control. With this control we can get latest native SP ListView within our SPFx WebPart.

We can start with new SPFx project:

yo @microsoft/sharepoint

Select WebPart as client-side component.

After project is created, install next dependency to your project. This is for SPFx React Controls.

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

Open project within Visual Studio Code.

code .

Go to config/config.json file and add the following line to the localizedResources property:

"ControlStrings": "./node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js"

Open IHelloWorldProps.ts file, update interface for our React component properties and create interface for our React component state. In properties we have current context. In state we create empty array for items in ListView.

import { WebPartContext } from '@microsoft/sp-webpart-base';

export interface IHelloWorldProps {
  context: WebPartContext;
}

export interface IHelloWorldState {
  items: any[];
}

Open HelloWorld.tsx file and add this two import statements:

import { ListView, IViewField, SelectionMode, GroupOrder, IGrouping } from "@pnp/spfx-controls-react/lib/ListView";
import { SPHttpClient } from '@microsoft/sp-http';

Then add constructor to your class extended from React.Component in which you have to initialize React Component state:

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

    this.state = {
      items: []
    };
}

Then we overwrite componentDidMount method which is called when React Component is mounted. In that method we call SharePoint REST API from which we get list items in specific list named Test sample list.

public componentDidMount() {
    const restApi = `${this.props.context.pageContext.web.absoluteUrl}/_api/web/lists/GetByTitle('Test sample list')/items`;
    this.props.context.spHttpClient.get(restApi, SPHttpClient.configurations.v1)
      .then(resp => { return resp.json(); })
      .then(items => {
        this.setState({
          items: items.value ? items.value : []
        });
      });
}

Then update render method. You need to define view fieldsgroup by fields and return ListView element.

public render(): React.ReactElement<IHelloWorldProps> {
    const viewFields: IViewField[] = [
      {
        name: 'Title',
        displayName: 'Last Name',
        sorting: true,
        maxWidth: 80
      },
      {
        name: 'FirstName',
        displayName: 'First Name',
        sorting: true,
        maxWidth: 80
      },
      {
        name: 'Company',
        displayName: "Company",
        sorting: true,
        maxWidth: 80
      },
      {
        name: 'WorkPhone',
        displayName: "Business Phone",
        sorting: true,
        maxWidth: 80
      },
      {
        name: 'HomePhone',
        displayName: "Home Phone",
        sorting: true,
        maxWidth: 80
      },
      {
        name: 'Email',
        displayName: "Email Address",
        sorting: true,
        maxWidth: 100,
        render: (item: any) => {
          return <a href={"mailto:" + item['Email']}>{item['Email']}</a>;
        }
      }
    ];
   
    const groupByFields: IGrouping[] = [
      {
        name: "Company",
        order: GroupOrder.ascending
      }
    ];

    return (
      <ListView
      items={this.state.items}
      viewFields={viewFields}
      iconFieldName="ServerRelativeUrl"
      compact={true}
      selectionMode={SelectionMode.multiple}
      selection={this._getSelection}
      groupByFields={groupByFields} />
    );
}

The last thing you need to do is to update creation of React Element from React Component in class extended from BaseClientSideWebPart. Find render method and put context inside createElement method.

public render(): void {
    const element: React.ReactElement<IHelloWorldProps > = React.createElement(
      HelloWorld,
      {
        context: this.context
      }
    );

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

[ Complete code on GitHub ]

Cheers!
Gašper Rupnik

{End.}

Advertisements

4 thoughts on “SPFx React Controls – ListView Control

Add yours

  1. awesome, well done and thank you.
    I still had to work for it but got there in the end.
    Some things you didn’t mention –
    * in Yeoman, make sure you select the “React” framework
    * You didn’t mention the IHelloWorldState changes you needed to make

    anyway, thanks again

  2. Thanks, This is very useful. I added a property to capture the name of the list to dynamically load the data from a list. But this part is not getting reloaded when I change the list name in the proprety pane. Is there any other methos that i need to override to make it work on property pane update?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Powered by WordPress.com.

Up ↑

%d bloggers like this: