Вопрос

I have created a command set for managing products that are saved in a SP list. Each product's categories are saved on a metadata column (terms ) on that list.

If any user suddenly needs to edit an existing registered product, a ProductEditor react component will be rendered, after triggering the command set action. This component must show any term(s) that user may have already entered, for that sp list item.

For displaying the terms selection control, I'm using the TaxonomyPicker from PnP. Here is a part of my ProductEditor component.

import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/TaxonomyPicker";

public render(): React.ReactElement<IProductEditorProps> {
    return (
        <TaxonomyPicker
            termsetNameOrID="xxx"
            context={this.props.webContext as WebPartContext}
            onChange={categories => { this.setState({ category: categories[0] }); }} /> 
    );
}

The problem is when I need to set the initial values of the component with the ones retrieved from the list column. I can retrieve any term data from the term store with code below:

let term: ITermData & ITerm = await taxonomy
    .termStores.getByName('xxx')             // --> The name of the term store.
    .getTermSetById('yyy'),                  // --> The GUID of the term set.
    .getTermById('zzz');                     // --> The GUID of the original selected term.
    .get();

However, the variabele term is type of ITermData & ITerm but the TaxonomyPicker.initialValues property requests an IPickerTerms. How can I cast this to the correct type and back for the onChange method?

A product can only have one category, what means, the column will only contain 1 term.

The sp rest API data shows the below information regarding the taxonomy column on the list item:

<d:Category m:type="SP.Taxonomy.TaxonomyFieldValue">
    <d:Label>11</d:Label>
    <d:TermGuid>zzz</d:TermGuid>                     <!-- The GUID of the original selected term. -->
    <d:WssId m:type="Edm.Int32">22</d:WssId>
</d:Category>

PS: I'm creating different edit buttons because there're fields dependent from other fields. More info here: Replace default "new" action to custom created command SPFX.

Это было полезно?

Решение

Not a big deal, just convert the termstore term to an object that follows the IPickerTerm type. Lets create a function like

async function convertTermPickerTerm (taxonomyTerm: ITermData & ITerm): Promise<IPickerTerm>  {
  let termset: ITermSetData & ITermSet = await taxonomyTerm.termSet.get();
  let termSet:string = termset.Id;
  const { Id: key, Name: name, PathOfTerm: path } = taxonomyTerm;
  return Promise.resolve( { key, name, path, termSet});
}

Then, after you have retrieved the details of the term already placed in your list column, just update your TaxonomyPicker component props:

import { TaxonomyPicker, IPickerTerms } from "@pnp/spfx-controls-react/lib/TaxonomyPicker";

public render(): React.ReactElement<IProductEditorProps> {
    return (
        <TaxonomyPicker
            termsetNameOrID="xxx"
            context={this.props.webContext as WebPartContext}
            initialValues = { [await convertTermPickerTerm (productTerm)] }
            onChange={categories => { this.setState({ category: categories[0] }); }} /> 
    );
}

That should work, good luck ;)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с sharepoint.stackexchange
scroll top