1

I'm trying to use Microsoft control PeoplePicker from UI Fabric to get an Office-feel in my app. I'm able to use control like Dropdown and button, but when I want to use PeoplePicker, I get error in code even if I change nothing.

To start my component code, I've copy-paste Normal People Picker from https://developer.microsoft.com/en-us/fabric#/controls/web/peoplepicker, and I get two error (for now).

  1. Line 48:66: Parsing error: Unexpected token, expected "," and my line 48 is :
    return peopleList.filter(item => doesTextStartWith(item.text as string, filterText));
    pointing item.text as string. I guess this error come from the use of as string in JS code. When I replace all as string to .toString(), the error disapear.
  2. Unexpected token (26:79) and my line 26 is :
    const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState<IPersonaProps[]>(mru);
    pointing [] after IPersonaProps.

Since I take code from Microsoft, and it's not working on my computer, I guess I'm missing something. I was expecting to get the same result as the sample on their website.

I have office-ui-fabric-react in my Node's module.

Here's my code :

import * as React from 'react';
import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox';
import { IPersonaProps } from 'office-ui-fabric-react/lib/Persona';
import { IBasePickerSuggestionsProps, NormalPeoplePicker, ValidationState } from 'office-ui-fabric-react/lib/Pickers';
import { people, mru } from '@uifabric/example-data';

const suggestionProps: IBasePickerSuggestionsProps = {
  suggestionsHeaderText: 'Suggested People',
  mostRecentlyUsedHeaderText: 'Suggested Contacts',
  noResultsFoundText: 'No results found',
  loadingText: 'Loading',
  showRemoveButtons: true,
  suggestionsAvailableAlertText: 'People Picker Suggestions available',
  suggestionsContainerAriaLabel: 'Suggested contacts'
};

const checkboxStyles = {
  root: {
marginTop: 10
  }
};

export const PeoplePickerNormalExample: React.FunctionComponent = () => {
  const [delayResults, setDelayResults] = React.useState(false);
  const [isPickerDisabled, setIsPickerDisabled] = React.useState(false);
  const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState<IPersonaProps[]>(mru);
  const [peopleList, setPeopleList] = React.useState<IPersonaProps[]>(people);

  const picker = React.useRef(null);

  const onFilterChanged = (
filterText: string,
currentPersonas: IPersonaProps[],
limitResults?: number
  ): IPersonaProps[] | Promise<IPersonaProps[]> => {
if (filterText) {
  let filteredPersonas: IPersonaProps[] = filterPersonasByText(filterText);

  filteredPersonas = removeDuplicates(filteredPersonas, currentPersonas);
  filteredPersonas = limitResults ? filteredPersonas.slice(0, limitResults) : filteredPersonas;
  return filterPromise(filteredPersonas);
} else {
  return [];
}
  };

  const filterPersonasByText = (filterText: string): IPersonaProps[] => {
return peopleList.filter(item => doesTextStartWith(item.text as string, filterText));
  };

  const filterPromise = (personasToReturn: IPersonaProps[]): IPersonaProps[] | Promise<IPersonaProps[]> => {
if (delayResults) {
  return convertResultsToPromise(personasToReturn);
} else {
  return personasToReturn;
}
  };

  const returnMostRecentlyUsed = (currentPersonas: IPersonaProps[]): IPersonaProps[] | Promise<IPersonaProps[]> => {
setMostRecentlyUsed(removeDuplicates(mostRecentlyUsed, currentPersonas));
return filterPromise(mostRecentlyUsed);
  };

  const onRemoveSuggestion = (item: IPersonaProps): void => {
const indexPeopleList: number = peopleList.indexOf(item);
const indexMostRecentlyUsed: number = mostRecentlyUsed.indexOf(item);

if (indexPeopleList >= 0) {
  const newPeople: IPersonaProps[] = peopleList.slice(0, indexPeopleList).concat(peopleList.slice(indexPeopleList + 1));
  setPeopleList(newPeople);
}

if (indexMostRecentlyUsed >= 0) {
  const newSuggestedPeople: IPersonaProps[] = mostRecentlyUsed
    .slice(0, indexMostRecentlyUsed)
    .concat(mostRecentlyUsed.slice(indexMostRecentlyUsed + 1));
  setMostRecentlyUsed(newSuggestedPeople);
}
  };

  const onDisabledButtonClick = (): void => {
setIsPickerDisabled(!isPickerDisabled);
  };

  const onToggleDelayResultsChange = (): void => {
setDelayResults(!delayResults);
  };

  return (
<div>
  <NormalPeoplePicker
    onResolveSuggestions={onFilterChanged}
    onEmptyInputFocus={returnMostRecentlyUsed}
    getTextFromItem={getTextFromItem}
    pickerSuggestionsProps={suggestionProps}
    className={'ms-PeoplePicker'}
    key={'normal'}
    onRemoveSuggestion={onRemoveSuggestion}
    onValidateInput={validateInput}
    removeButtonAriaLabel={'Remove'}
    inputProps={{
      onBlur: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onBlur called'),
      onFocus: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onFocus called'),
      'aria-label': 'People Picker'
    }}
    componentRef={picker}
    onInputChange={onInputChange}
    resolveDelay={300}
    disabled={isPickerDisabled}
  />
  <Checkbox label="Disable People Picker" checked={isPickerDisabled} onChange={onDisabledButtonClick} styles={checkboxStyles} />
  <Checkbox
    label="Delay Suggestion Results"
    defaultChecked={delayResults}
    onChange={onToggleDelayResultsChange}
    styles={checkboxStyles} />
</div>
  );
};

function doesTextStartWith(text: string, filterText: string): boolean {
  return text.toLowerCase().indexOf(filterText.toLowerCase()) === 0;
}

function removeDuplicates(personas: IPersonaProps[], possibleDupes: IPersonaProps[]) {
  return personas.filter(persona => !listContainsPersona(persona, possibleDupes));
}

function listContainsPersona(persona: IPersonaProps, personas: IPersonaProps[]) {
  if (!personas || !personas.length || personas.length === 0) {
return false;
  }
  return personas.filter(item => item.text === persona.text).length > 0;
}

function convertResultsToPromise(results: IPersonaProps[]): Promise<IPersonaProps[]> {
  return new Promise<IPersonaProps[]>((resolve, reject) => setTimeout(() => resolve(results), 2000));
}

function getTextFromItem(persona: IPersonaProps): string {
  return persona.text as string;
}

function validateInput(input: string): ValidationState {
  if (input.indexOf('@') !== -1) {
return ValidationState.valid;
  } else if (input.length > 1) {
return ValidationState.warning;
  } else {
return ValidationState.invalid;
  }
}

/**
 * Takes in the picker input and modifies it in whichever way
 * the caller wants, i.e. parsing entries copied from Outlook (sample
 * input: "Aaron Reid <aaron>").
 *
 * @param input The text entered into the picker.
 */
function onInputChange(input: string): string {
  const outlookRegEx = /<.*>/g;
  const emailAddress = outlookRegEx.exec(input);

  if (emailAddress && emailAddress[0]) {
return emailAddress[0].substring(1, emailAddress[0].length - 1);
  }

  return input;
}

and I use it like this in my App. I've put <...> to keep code short. Everything is working in this section.

import React from 'react';
import { Fabric } from 'office-ui-fabric-react/lib/Fabric'
import PeoplePickerNormalExample from "./components/MyCustom_Picker.js"

class App extends React.Component {
  render() {
    return ( 
      <Fabric className = "App" >
        <PeoplePickerNormalExample / >
        <...>
      </Fabric>
    );
  }
}

export default App;

1 Answers1

0

I don't think your app is in Typescript (TS). The Office UI examples you're copying are in TS. To convert the examples back into vanilla JS, remove the types (e.g. : string, : number, : IPersonaProps[]).

Check out this link: https://www.typescriptlang.org/play/. Paste the sample code in there to try to covert it to JS.

mirage
  • 708
  • 3
  • 8
  • Thank you for your answser. I've use the website you provide me and now the control appear on my page without error. The fact that all others control from Microsoft was working as JS fooled me. – LordOptimistic Mar 23 '20 at 13:03