将组合框绑定到共享点列表

Bind combobox to sharepoint list

此代码展示了如何使用 React 在 Sharepoint 在线 Web 部件中使用组合框。示例数据是硬编码的。如何将组合框绑定到 Sharepoint 列表?

```
import * as React from 'react';
import { ComboBox, Fabric, IComboBoxOption, mergeStyles, 
SelectableOptionMenuItemType, Toggle } from 'office-ui-fabric- 
react/lib/index';

const INITIAL_OPTIONS: IComboBoxOption[] = [
 { key: 'Header1', text: 'First heading', itemType: 
SelectableOptionMenuItemType.Header },
 { key: 'A', text: 'Option A' },
{ key: 'B', text: 'Option B' },
{ key: 'C', text: 'Option C' },
{ key: 'D', text: 'Option D' },
{ key: 'divider', text: '-', 
itemType: SelectableOptionMenuItemType.Divider },
{ key: 'Header2', text: 'Second heading', itemType: 
SelectableOptionMenuItemType.Header },
 { key: 'E', text: 'Option E' },
 { key: 'F', text: 'Option F', disabled: true },
 { key: 'G', text: 'Option G' },
 { key: 'H', text: 'Option H' },
 { key: 'I', text: 'Option I' },
 { key: 'J', text: 'Option J' }
  ];

  const wrapperClassName = mergeStyles({
  display: 'flex',
  selectors: {
  '& > *': { marginRight: '20px' },
  '& .ms-ComboBox': { maxWidth: '300px' }
  }
  });

  export interface IComboBoxTogglesExampleState {
  autoComplete: boolean;
  allowFreeform: boolean;
 }

 // tslint:disable:jsx-no-lambda
 export class ComboBoxTogglesExample extends React.Component<{}, 
 IComboBoxTogglesExampleState> {
 public state: IComboBoxTogglesExampleState = {
 autoComplete: false,
 allowFreeform: true
 };

public render(): JSX.Element {
const state = this.state;
return (
  <Fabric className={wrapperClassName}>
    <ComboBox
      label="ComboBox with toggleable freeform/auto-complete"
      key={'' + state.autoComplete + state.allowFreeform /*key causes re- 
    render when toggles change*/}
      allowFreeform={state.allowFreeform}
      autoComplete={state.autoComplete ? 'on' : 'off'}
      options={INITIAL_OPTIONS}
    />
    <Toggle
      label="Allow freeform"
      checked={state.allowFreeform}
      onChange={(ev: React.MouseEvent<HTMLElement>, checked?: boolean) => 
   {
        this.setState({ allowFreeform: !!checked });
      }}
    />
    <Toggle
      label="Auto-complete"
      checked={state.autoComplete}
      onChange={(ev: React.MouseEvent<HTMLElement>, checked?: boolean) => 
  {
        this.setState({ autoComplete: !!checked });
      }}
    />
  </Fabric>
  );
  }
}
```

这是使用 React Framework 的 Sharepoint Online webpart。

我有一个包含 60 个成本中心的列表,我希望它们显示在一个组合框中并打开自动完成功能。

示例演示(很多测试场景,只检查您需要的逻辑):

export interface IListItem{
  Id: number;
  Title: string;
  Body : {
           Body_p1: string;
           Body_p2: string;
  };
}

export interface IReactExState{
  controlName:string,
  ControlValue:string,
  windowsID:number,
  showPanel:boolean,
  items: IListItem[],
  Options:IComboBoxOption[],
  selectionDetails: {},
  showModal: boolean,
  autoComplete: boolean,
  allowFreeform: boolean
}

export default class OfficeFabric extends React.Component<IOfficeFabricProps, IReactExState> {

  private _selection: Selection;
  private _allItems: IListItem[];
  private _columns: IColumn[];

  public constructor(props: IOfficeFabricProps,state: IReactExState){ 
    super(props); 
    this._selection = new Selection({
      onSelectionChanged: () => this.setState({ selectionDetails: this._getSelectionDetails() })
    });
    this._allItems = [
      {
        Id   : 0,
        Title : "test0",
        Body : {
                 Body_p1: "test0_p1",
                 Body_p2: "test0_p2"
               },
       },
       {
        Id  : 1,
        Title : "test1",
        Body : {
                 Body_p1: "test1_p1",
                 Body_p2: "test1_p2"
               }
       }
     ];
    this._columns = [
      { key: 'Id', name: 'Id', fieldName: 'Id', minWidth: 100, maxWidth: 200, isResizable: true },
      { key: 'Title', name: 'Title', fieldName: 'Title', minWidth: 200, maxWidth: 400, isResizable: true },
      { key: 'Body', name: 'Body', minWidth: 200, maxWidth: 400, isResizable: true,onRender: (item) => (
        <div>          
         {item.Body.Body_p1}
          </div>) },
  ];
    this.state = { 
      controlName:"",
      ControlValue:"",
      windowsID:123.4,
      showPanel:false,
      items:this._allItems,
      Options:[],
      selectionDetails: this._getSelectionDetails() ,
      showModal:false,
      autoComplete: false,
      allowFreeform: true
    }; 
  }

  private _showModal = (): void => {
    this.setState({ showModal: true });
  };

  private _closeModal = (): void => {
    this.setState({ showModal: false });
  };

  private _getSelectionDetails(): string {
    const selectionCount = this._selection.getSelectedCount();

    switch (selectionCount) {
      case 0:
        return 'No items selected';
      case 1:
        return '1 item selected: ' + (this._selection.getSelection()[0] as IListItem).Title;
      default:
        return `${selectionCount} items selected`;
    }
  }

  private _onItemInvoked = (item: IListItem): void => {
    alert(`Item invoked: ${item.Title}`);
  };

  private _showPanel = () => {
    this.setState({ showPanel: true });
  };

  private _hidePanel = () => {
    this.setState({ showPanel: false });
  };
  private _Save = () => {
    //to do save logic
    this.setState({ showPanel: false });
    alert('save clicked');
  };
  private _onRenderFooterContent = () => {
    return (
      <div>
        <PrimaryButton onClick={this._hidePanel} style={{ marginRight: '8px' }}>
          Save
        </PrimaryButton>
        <DefaultButton onClick={this._showPanel}>Cancel</DefaultButton>
      </div>
    );
  };

  public componentDidMount(){    
    var reactHandler = this;    
    this.props.context.spHttpClient.get(`${this.props.context.pageContext.web.absoluteUrl}/_api/web/lists/getbytitle('TestList')/items?select=ID,Title`,
    SPHttpClient.configurations.v1) .then((response: SPHttpClientResponse) => {  
      response.json().then((responseJSON: any) => {
        let tempOptions:IComboBoxOption[]=[];
        responseJSON.value.forEach(element => {
          tempOptions.push({key:element.ID,text:element.Title})
        });
        reactHandler.setState({
          Options: tempOptions
        });
      });  
    }); 
  }
  // private _onJobTitReportToChange = (ev: React.FormEvent<HTMLInputElement>, newValue?: string) => {
  //   this.props.onJobTitleReportToChange(newValue);
  // }

  public handleObjectWithMultipleFields  = (ev, newText: string): void => {
    const target = ev.target;
    const value = newText; 
    var _ControlName=target.name;

    this.setState({
      controlName: _ControlName,
      ControlValue:value
    })
  }
  public render(): React.ReactElement<IOfficeFabricProps> {
    return (
      <div className={ styles.officeFabric }>
        <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>

              <ComboBox
              label="ComboBox with toggleable freeform/auto-complete"
              key={'' + this.state.autoComplete + this.state.allowFreeform /*key causes re- 
            render when toggles change*/}
              allowFreeform={this.state.allowFreeform}
              autoComplete={this.state.autoComplete ? 'on' : 'off'}
              options={this.state.Options}
            />
              <TextField name="txtA" value={this.state.windowsID.toString()}
           onChange={this.handleObjectWithMultipleFields}/>

              <TextField name="txtB"
           onChange={this.handleObjectWithMultipleFields}/>
              <div>
        <DefaultButton secondaryText="Opens the Sample Panel" onClick={this._showPanel} text="Open Panel" />
        <Panel
          isOpen={this.state.showPanel}
          type={PanelType.smallFixedFar}
          onDismiss={this._hidePanel}
          headerText="Panel - Small, right-aligned, fixed, with footer"
          closeButtonAriaLabel="Close"
          onRenderFooterContent={this._onRenderFooterContent}
        >
          <DefaultButton className={styles.tablink} text="Button" />
          <ChoiceGroup
            options={[
              {
                key: 'A',
                text: 'Option A'
              },
              {
                key: 'B',
                text: 'Option B',
                checked: true
              },
              {
                key: 'C',
                text: 'Option C',
                disabled: true
              },
              {
                key: 'D',
                text: 'Option D',
                checked: true,
                disabled: true
              }
            ]}
            label="Pick one"
            required={true}
          />
        </Panel>

        <DefaultButton secondaryText="Opens the Sample Modal" onClick={this._showModal} text="Open Modal" />

      </div>
              <MarqueeSelection selection={this._selection}>
              <DetailsList
                items={this.state.items}
                columns={this._columns}
                setKey="set"
                layoutMode={DetailsListLayoutMode.justified}
                selection={this._selection}
                selectionPreservedOnEmptyClick={true}
                ariaLabelForSelectionColumn="Toggle selection"
                ariaLabelForSelectAllCheckbox="Toggle selection for all items"
                checkButtonAriaLabel="Row checkbox"
                onItemInvoked={this._onItemInvoked}
              />
            </MarqueeSelection>
              <a href="https://aka.ms/spfx" className={ styles.button }>
                <span className={ styles.label }>Learn more</span>
              </a>
              <Icon iconName='Mail' />
              <br/>
              <Icon iconName='CirclePlus' />
              <br/>
              <Icon iconName='LocationDot' />
            </div>
          </div>
        </div>
      </div>
    );
  }
}

我最终使用了这个。

sp.web.lists.getByTitle("ChartOfAccounts").items.getAll().then((result: any)=>{
  for(let i: number = 0; i< result.length; i++) {
    const b: SPData = result[i];
    const c: IComboBoxOption={key:b.Column1, text: b.CostCentreInfo};
    INITIAL_OPTIONS.push(c);
}