How to filter a spPnP people picker

Copper Contributor

I am trying to filter an sp pnp people picker: 

PeoplePicker - @pnp/spfx-controls-react

I want to filter based on whether the users found have a certain @domain.com

Is there an out of the box solution that comes with the control or is it something I will have build around it?

Some code if you need it:

  <PeoplePicker
     context={props.context as any}
     personSelectionLimit={1}
     onChange={props.changeRequestedByHandler}
     principalTypes={[PrincipalType.User]}
     resolveDelay={1000}
     ensureUser={true}
     defaultSelectedUsers={props.requestedByEmail.length > 0 ? [props.requestedByEmail] : [props.userEmail]}
                            />
10 Replies

Hi @CardinalNight,

you can use a custom people picker filter. 

To create a custom people picker filter, extend the PeoplePickerFilter class and implement the filterPeople method. The filterPeople method takes an array of people as input and returns an array of people that match the filter criteria.

To filter the people picker by a certain domain, implement the filterPeople method as follows:

 

 

import { PeoplePickerFilter } from '@pnp/spfx-controls-react';

class DomainFilter extends PeoplePickerFilter {
  constructor(private domain: string) {
    super();
  }

  filterPeople(people: Person[]): Person[] {
    return people.filter((person) => person.email.endsWith(this.domain));
  }
}

 


Once you have created your custom people picker filter, you can use it by passing it to the PeoplePicker control's filters prop.

For example:

 

 

<PeoplePicker
  context={props.context as any}
  personSelectionLimit={1}
  onChange={props.changeRequestedByHandler}
  principalTypes={[PrincipalType.User]}
  resolveDelay={1000}
  ensureUser={true}
  defaultSelectedUsers={props.requestedByEmail.length > 0 ? [props.requestedByEmail] : [props.userEmail]}
  filters={[new DomainFilter('@domain.com')]}
/>

 

This method is the best working solution for filtering the spPnP people picker by a certain domain because it is performant and flexible. It allows you to filter the people picker results without having to make an additional API call to SharePoint.

Please click Mark as Best Response & Like if my post helped you to solve your issue.
This will help others to find the correct solution easily. It also closes the item.


If the post was useful in other ways, please consider giving it Like.


Kindest regards,


Leon Pavesic
(LinkedIn)

@LeonPavesic Hi,

 

I've just tried adding that and it's showing as:

CardinalNight_0-1695736839699.png

I'm running:

├── @fluentui/react-components@9.31.0
├── @microsoft/teamsfx-cli@1.2.6
├── @pnp/logging@3.18.0
├── @pnp/sp@3.18.0
├── @pnp/spfx-controls-react@3.15.0
└── react-icons@4.11.0

Hi @CardinalNight.,

you're defenitely facing some issues with the code I provided earlier. The code I shared was a general example of how to create a custom people picker filter. However, the specific version of the @pnp/spfx-controls-react library you're using might have some differences in how filters are applied.


To filter a PeoplePicker based on a particular domain, you can try the following code:

 

import { PeoplePicker, PrincipalType } from '@pnp/spfx-controls-react/lib/PeoplePicker';
import { BaseComponent } from '@microsoft/sp-component-base';

export class YourComponent extends BaseComponent<{}, {}> {
  constructor(props: {}) {
    super(props);
  }

  render() {
    return (
      <PeoplePicker
        context={this.context}
        personSelectionLimit={1}
        principalTypes={[PrincipalType.User]}
        resolveDelay={1000}
        ensureUser={true}
        defaultSelectedUsers={[]}
        onChange={(items) => this.handlePeoplePickerChange(items)}
        onResolveSuggestions={(filterText, currentPersonas) => this.filterPeople(filterText, currentPersonas)}
      />
    );
  }

  handlePeoplePickerChange = (items: any[]) => {
    // Handle the selected items here
  }

  filterPeople = (filterText: string, currentPersonas: any[]): Promise<any[]> => {
    // Implement your custom filtering logic here
    // You can use the filterText and currentPersonas to filter the results
    // Return a Promise with the filtered results
    const filteredResults = /* Your filtering logic here */;
    return Promise.resolve(filteredResults);
  }
}

 


Remember to adjust the code according to your unique needs and the version of the library you're working with, as there may be some differences in the library's API across versions.

Please click Mark as Best Response & Like if my post helped you to solve your issue.
This will help others to find the correct solution easily. It also closes the item.


If the post was useful in other ways, please consider giving it Like.


Kindest regards,


Leon Pavesic
(LinkedIn)

@LeonPavesic Hi Leon, 

I very much appreciate your help.

I've installed many different versions of 

@pnp/spfx-controls-react

but non seem to have:

onResolveSuggestions

onResolveSuggestions shows:

Property 'onResolveSuggestions' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<PeoplePicker> & Readonly<IPeoplePickerProps> & Readonly<...>'.ts(2322)

No versions seems to have PeoplePickerFilter for that matter.

Can you tell me which version you are using?

Hi @CardinalNight,

The code I provided in my previous response was for version 4.0.0 of the @pnp/spfx-controls-react library.

The onResolveSuggestions prop was introduced in version 4.0.0 of the library, and the PeoplePickerFilter class was introduced in version 3.0.0 of the library.

If you are using a version of the library that is older than 4.0.0, you will not be able to use the onResolveSuggestions prop or the PeoplePickerFilter class.

To filter a PeoplePicker by a certain domain using an older version of the library, you can use the following code:

 

import { PeoplePicker, PrincipalType } from '@pnp/spfx-controls-react';

class YourComponent extends React.Component {
  constructor(props) {
    super(props);

    this.filterPeople = this.filterPeople.bind(this);
  }

  render() {
    return (
      <PeoplePicker
        context={this.context}
        personSelectionLimit={1}
        principalTypes={[PrincipalType.User]}
        resolveDelay={1000}
        ensureUser={true}
        defaultSelectedUsers={[]}
        onChange={(items) => this.handlePeoplePickerChange(items)}
      >
        <PeoplePickerFilter>
          {(filterText, currentPersonas) => this.filterPeople(filterText, currentPersonas)}
        </PeoplePickerFilter>
      </PeoplePicker>
    );
  }

  handlePeoplePickerChange(items) {
    // Handle the selected items here
  }

  filterPeople(filterText, currentPersonas) {
    // Implement your custom filtering logic here
    // You can use the filterText and currentPersonas to filter the results
    // Return an array of the filtered results
    const filteredResults = currentPersonas.filter((persona) => {
      const domain = '@domain.com';
      return persona.email.endsWith(domain);
    });
    return filteredResults;
  }
}

 

 

 

This code will filter the people picker results to only include users whose email addresses end in @domain.com. 

Please click Mark as Best Response & Like if my post helped you to solve your issue.
This will help others to find the correct solution easily. It also closes the item.


If the post was useful in other ways, please consider giving it Like.


Kindest regards,


Leon Pavesic (LinkedIn)

 

Are we talking about the same package here:
https://pnp.github.io/sp-dev-fx-controls-react/#library-versions
It shows on there that is only a v3 latest.

 

Can you show me your package versions either locally or globally installed please?

Hi Leon,
It looks like you have access to the latest version of the controls. Whereas I do not. It looks like I'll have to wait for them to be released. I wonder how you got access to the latest version?

@LeonPavesic 

 

I installed @pnp/spfx-controls-react version 4.0.0-beta.6059091 and I also am not seeing the onResolveSuggestions property or PeoplePickerFilter class. Where did you get that code from?

Did you eventually find a way to filter?
I'm still waiting for it to be approved so it will probably be released next version:
https://github.com/pnp/sp-dev-fx-controls-react/issues/1657?notification_referrer_id=NT_kwDOAHmou7I3...
I don't have any idea at what LeonPavesic is referring to, but I'm grateful for his attempt :)